This member has provided no bio about themself...

Report RSS Porting Toxic Bunny HD to Windows 8 in Unity

Posted by on

OK so few of you might know this but we actually started the whole Unity port with Windows 8 in mind from the beginning. In Feb we were chatting to Dave Russel from Microsoft SA. He brought the Windows 8 opportunity to our attention. That's not to say we haven't seen many other advantages porting Toxic Bunny HD to Unity along the way. But now we on the last leg of that process. Porting to Windows 8 mobile.

Just to clarify I am personally finding the branding around Windows 8 mobile space a little confusing. So to clarify I am talking about Mobile Phone OS Win 8.

Our first run hit a brick wall, black screen nothing happened eventually a heap overflow. Not a great start, but not uncommon with mobile ports. We had the same issues when porting to Android for the GameStick. We have already shaved the draw calls down to about 20 so we have confidence there, so what next.

Where you live counts !?

What caught us off guard was a few complete gotchas. The biggest relating to differences in the Microsoft CLR and the Mono one Unity usually uses. For our game we have a custom sprite atlas. We store the UV positions in a nice and neat text file like so.

0,0.0,0.0,0.09765625,0.09765625 0,0.0,0.109375,0.09765625,0.09765625 0,0.0,0.21875,0.09765625,0.09765625 0,0.0,0.328125,0.09765625,0.09765625 0,0.0,0.4375,0.09765625,0.09765625 0,0.0,0.546875,0.09765625,0.09765625 0,0.0,0.65625,0.09765625,0.09765625 0,0.0,0.765625,0.09765625,0.09765625

Arguably not elegant but it gets the job done and is only an "on load" issue so not something we plan to change. Its also the source of our first issue. We get a Number format error exception (caught in Visual Studio when running the game from there, highly recommended to run out of VS and Unity during your debugging phase not just one or the other). So comes down to the following lines of code.

csharp code:
u=float.Parse(parts[1]);
v=1f-float.Parse(parts[2]);

The solution was struggling to convert "0.0" into a float. It appears here in South Africa we supposedly use a "," as out decimal point. I will admit that's news to me as a South African but non the less the Microsoft framework was correctly looking for "0,0" in accordance with our country code. I am grateful we caught this here as apposed to finding out later when run in another country that uses a ",".

This is easily solved by changing all parse methods to the following (This works fine on the Win 8 phones and standard desktop).

csharp code:
u=float.Parse(parts[1],  System.Globalization.CultureInfo.InvariantCulture.NumberFormat); v=1f-float.Parse(parts[2], System.Globalization.CultureInfo.InvariantCulture.NumberFormat);

Once this was changed we got the game up and running at a stunning 1 fps. Its a start even if a slow one. The next trick was to find the main causes of pain and steadily remove them. Below is a snap shot from the profiler, edited to fit the screen better for the blog.

Starting Picture

I still do not know what "Overhead" is I can only hope its an overhead that goes away when I am not profiling.

Of interest is the highlighted line. Mesh.CreateVBO. There are many ways to cause these calls. In our case the issue was scaling. Each time a sprite changes we scale the holding box in case that sprite is a different size on the screen.

csharp code:
transform.localScale=sl.size*gfxscale;

Unity creates a new mesh each time we scale. This is an unfortunate but seemingly necessary thing for Unity to do. Essentially though we hardly ever actually need to re scale the sprites are almost always exactly the same size. The following code removed this issue.

csharp code:
Vector3 newScale=sl.size*gfxscale;
if (transform.localScale!=newScale){
transform.localScale=newScale;
 

So only change it when you need to dropped 16-32ms from our process. This extended to all many of other areas esp nGUI ui where we scaled health bars and life bars each frame. These optimizations gained us another 10ms or so per frame.

Small sound issue worth mentioning.

When you run the application from Unity onto your phone any streamed music will stutter. This goes away when you run from VS with the application in Master mode. Nuff said.

OnGUI nooooo!

Before I started using Unity on mobile I had no idea why people were so against the OnGUI methods. I thought it was mostly about DrawCalls. Man did this experience show that to be wrong. OnGUI added more then 14ms just for preparation. The total OnGUI cost for a FPS counter was 22ms. All OnGUI gui is removed and has been replaced with nGUI.

Mob Updates.

On most Toxic Bunny levels there are about 600-800 monsters. (Getting progressively more as you move to later levels. To reduce the overhead all monsters check if they are in range before running there script. The code looks as follows.

csharp code:
public void FixedUpdate() {
if (!shouldThink()){
return ;  

This seamed good enough at the time. But now we see 300+ Rat scripts been called costing us 8-12ms. With 4 mobs on the level the total costs there added up to about 40-60ms. The answer is to switch the script off completely when out of range as apposed to having a fall through function. We poly-morphed the shouldThink function and added one new Class to each monster object.

csharp code:
// This code from a ThinkAgain script attached to the monster
public void OnBecameVisible() {
monsterScript.enabled=true;
}// This code from the monster base class
s
public override bool shouldThink(){
bool soThinking=base.shouldThink();
if (!soThinking){
this.enabled=false;
}
retur

Now when a monster is far enough away it should stop thinking we actually disable the script. The script then automatically is enabled when that monster returns into the view as Unity will call OnBecameVisible for us that will enable the script.

Results.

As you can see out end of day one looks much better. That having been said we now need to add some of the parts back into the game. Some things that needed OnGUI must be re written to nGUI (This was to be expected)

End of day one profile

From despair to pretty pleased with the results. We have learned a lot about optimizing for Unity and esp Unity on Windows 8 Mobile and are now spending time on controls and scaling features for small phone screens.

This also blogged here Blog.celestial-games.com

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: