iOS Game Performance

Hi everyone. It takes a long time, until I give up reading threads and start my own. But for now, I’m done with trying to handle my performance problem :smile:

I am building a iPhone App thats seems to have so problems with performance on my iPod 4G. I tried everything to get down draw calls, etc., but sometimes, there are some peeks and I cant figure out, whats happening. Here is an image of my profiler:

For some explanation, I am using the PauseController from the Asset Store and also the NGUI Plugin, which seems to work fine.

Here is an image of my projects hierarchy, so you see, there arent that much items, except the grass (hair) on the sides, which are culled anyway.

Thank you in advance for every tip you have got.

So far I am using:

• pragma strict
• dynamic batching
• occlusion culling
• almost nothing in my updates except the player movement and the score calculation
• and lots of thread reading and trying a bunch of scripts to simplify that whole game

If just checked the meshes and there seem to be 41 Meshes in the Memory, even if I disable all elements in the hierarchy.

firstly there’s a bit of an art to using the profiler. Here’s a small guide:

  1. Usually you will want the brown garbage collection button selected first (turn the rest off - the small squares are CLICKABLE)
  2. remove all but scripts in profiler

if (Garbage)
{
RemoveGarbage();
}

Repeat that loop until done (no real choice).

  1. now disable garbage and enable Rendering and Scripts (blue and green).

Let the game run (chug) for a while then pause the profiler and track down the spikes. Watch the things that stay near the top a lot, work top-down and eliminate the slowdowns.

If when running profiler on desktop, you find the same sort of scripts being near the top as on mobile (rendering probably will not!) then enable deep profiling (unavailable on mobile) and get to the root of the problem. Beware of input stuff - that spews garbage if not careful (but its ok if it spews garbage on desktop).

If you need more tips after just post.

I took a look at the screenshot. Rendering is around 17 ms (so will probably hop between 60fps and below - shaders will likely optimise this, see my sig)

As for the main culprit - physics -

you need to make sure EVERY SINGLE physics object you’re moving has a rigidbody on it. Without fail. If it moves, put a rigid body on it. Don’t miss a single one.

Do you mean objects like the main character, or, in this example, the world, which is rotating dependent on the speed of the game and all hair objects inside?

Oh, and of course, thank you for you reply!!! :slight_smile:

Anything that rotates, scales or moves which has the Collider component - even a trigger - must have a rigidbody. If moving these things using transform, simply set rigidbody to isKinematic and disable gravity.

Otherwise you will get game-breaking slowdowns as physx recalculates lookup tables.

If I have got a GameObject, here “world”. There are 8 more empty gameObjects inside where every gameObject contains of 5 Meshes, thats the hair on the sides. Should i also give a rigidbody to this empty gameObjects or just the meshes? I’m trying to give everything a rigid body, but for now, I am maybe missing something.

http://1st-issue.de/downloads/profiler.png

as you can see, there are now 31 Rigidbodies.

Firstly I’ve no idea what you mean by hair or whatever that is. If it moves, add a rigidbody to it IF it has colliders. If its a lot of things that will move together, make a compound collider (see docs).

Secondly, it looks like your rendering is the bottleneck now, so you’ll want to optimise shaders, and simply reduce fill rate. Also, you’re still spewing garbage from multiple sources, this will cause hiccups in gameplay often.

Thanks for your advice. So I had to remove some rigidbodies, because, as you can see in my screenshot with the scene view, there is “hair” on the right, this is attached to the floor which is a sphere rotating according to the speed. So I just give a rigidbody to this gameObject instead of every single hair without colliders. So I dont need this compound colliders.

For your second advice, can you give me a tip where I can reduce those different sources for the garbage. Cant find something in the docs or anywhere else, where it could be.

Thank you for your time!

Just an update. I just found a script that combines all my meshes inside my world that consists of the sphere itself and some “hair” Objects:

http://wiki.unity3d.com/index.php?title=MeshMerger

Got down my draw calls from 22 to 13.

up to 20-30 drawcalls are fine on 3GS (weakest device available for drawcalls due to CPU power)

The focus must surely now be on shader performance and fill rate (or poly count etc) - let us know how you get on and lets get this between 30-60 fps :slight_smile:

As for know, the script of combining meshes did a good job, and I also tried to compress down all my textures to 256 or 512 if needed and compression quality to “Fast”. I’ve just got 5 Materials now and about 5 Textures including 1 Atlas for the UI. But there seems to be a problem with opaque geometry, dunno if it is really problem, just got this spike here:


http://1st-issue.de/downloads/profiler_2.png

Here is another image without that spike, could performance I think except that spikes coming from no

Those can be due to the gpu loading new graphics or models as you get to them in the scene, you can avoid that by rendering them all once for 1-2 frames behind a black screen just to be sure.

I can’t see any create VBO stuff, so I assume you’re not dynamically making meshes (if you are use MarkDynamic if using u4).

One word of warning, creating / destroying colliders can hit performance as well as changing them from kinematic to non kinematic. Hard to say at this point what the spikes might be. The garbage collector hit is usually delayed so you don’t see it on the profiler as the cause. If you are creating garbage, you need to deal with it, as it usually is the cause of lone spikes.

What I mean is if you see any bytes allocated, you have to deal with it. If you are using .transform from contact point hit or raycast hit, this will allocate bytes as well and eventually add up.

To solve that, is easy. Make a dictionary and add all colliders to it, and store the transforms. Then when you collide and need the transform, you just look it up in the dictionary and pass the collider from hit.collider.

This is because for some reason collider does not allocate bytes and transform does. It’s a bit sloppy on unity’s part here IMHO, none of their stuff has any business allocating garbage. If you allocate garbage, create or destroy, you need to deal with it on iOS if you want to ensure you are spike free.

You probably know all this, but it doesn’t hurt to make sure.

Bookmarking this thread as its full of hippos wisdom.

Thanks for you reply and information, sry that I am answering but now, enjoyed the non work easter weekend :wink: Yeah, you are right, I’m just creating a number of items, about 20 at the start, put them in position them with a raycast from the middle of a sphere and then just use occlusion culling and while they are not visibile repositioning them until they get visible again. Maybe thats one point, because they are repositioned on Update, trying to fix this.

I don’t really know, what you mean. What kind of transform do you mean. Here is a example what collides in this game world. (would be the easiest if I’m sending you the project and pay you for your help :smile: ;)) The main character is running over this sphere. Here is a collision stay going on, so i know he is grounded. Then there are gameobjects which either stop the character from running, or attach to him and give him a boost or sth.

Is there maybe a tutorial or workpath for handling with this garbage? As i said, ive been travelling through forums etc. to find out, what I could do. Thanks for any advice !