Avoid "tag" in iphone?

I am trying to optimize my game.
It is a 3D space arcade, I load 3 models in game -asteroid, spaceship and enemy- that share the same small texture, and models are batched well ( 10 asteroids and 5 enemies that are merged into 2 drawcalls).

So I am under 7000 triangles and 30 drawcalls, with less than 30fps average and as low as 15fps (with close particle effects) in a 3GS.

I can’t find room to optimize, so I am looking into the code. I use tags to know if the player collides vs an asteroid, laser, rocket or an enemy (same for enemy ships).
Should I avoid using tags? if so, how can I know wich is the collider?

thank you mates.

generally avoid strings or reduce their usage to a minimum as you generate a lot of work for the gc which can cause hickups. it would though not reduce the performance on a permanent base, thats more caused by the amount of data going through (potentially fillrate).
I would check if your particle effects are just overdoing it. if you are firing in a thousand particles or alike, that would be the first place to start optimizing.

You might want to use the profiler actually by enabling it in the xcode defines to see whats really eating the cpu time

thank you dreamora for your quick response.

The particles are only present when a ship explodes… and it is not so often, and only makes the game lag if you go through them (are those particles messing with physics?) I will check the profiler this afternoon and post it.
what worries me is that I have the same framerate (28fps) when my ship is alone in the space, with nothing else, so no fillrate problems.

you can watch a beta video here.

In that case I would recommend to run it with the profiler and post a few profiler snapshots so we can potentially tell you what might be the cause.

particle and physics would be a cause if they could collide, but I guess you disabled that in the particle emitter right?

iPhone Unity internal profiler stats:
cpu-player>    min:  7.2   max: 19.4   avg: 13.9
cpu-ogles-drv> min:  3.3   max:  5.6   avg:  4.2
cpu-present>   min:  1.5   max:  3.7   avg:  1.8
frametime>     min: 32.3   max: 37.8   avg: 34.8
draw-call #>   min:  20    max:  23    avg:  22     | batched:    11
tris #>        min:  5554  max:  6355  avg:  5850   | batched:  3298
verts #>       min:  2812  max:  3165  avg:  2934   | batched:  1304
player-detail> physx:  1.6 animation:  0.0 culling  0.5 skinning:  0.0 batching:  1.3 render:  6.8 fixed-update-count: 0 .. 1
mono-scripts>  update:  1.9   fixedUpdate:  0.7 coroutines:  0.2 
mono-memory>   used heap: 286720 allocated heap: 356352  max number of collections: 1 collection total duration:  2.7

I did some tweaks on Timestep, and peformance is a bit higher now.
What can you extract from the profler?
do I expect much lower peformance in slower devices like 2G? (going to be tested soon)

on pre 3GS you can expect it to be 30-50% slower

most of your time goes into rendering. as you don’t have that much geometry wise going on I would assume you either have massive sized textures or a lot of stuff that draws on top of the others or things that use non-optimal shaders (alpha test)

what I have mainly:

skybox 512x512 x 6 PVRTC 2 RGB (may skybox not be compressed to TC2?, I see no difference ingame)
1 texture shared for 4 items, 128x128 PVRTC 2 RGB
1 texture shared for asteroids, 256 x 256 PVRTC4 RGB
1 texture shared for spaceships, 256 x 256 PVRTC4 RGB (with 128x128 alpha)
3 textures 64x64 PVRTC 4 RGBA for GUI.

materials:
iphone/selfilumniation/vertex lit (for spaceships)
particles/additive
vertexlit (for asteroids)
a trailrender, and some glows

I think this is not that much… and no transparent textures at all!

I tried desabling all glows from spaceships, same framerate and render rate.
I disabled asteroids, and keep being more and less the same.
So I decided to disable the light.
Performance is the same, but polycount is much less (this part was expected)

iPhone Unity internal profiler stats:
cpu-player>    min:  6.3   max: 12.4   avg:  8.4
cpu-ogles-drv> min:  2.0   max:  5.4   avg:  2.6
cpu-present>   min:  1.4   max:  2.8   avg:  1.7
frametime>     min: 33.2   max: 37.4   avg: 34.8
draw-call #>   min:  17    max:  17    avg:  17     | batched:     0
tris #>        min:  1418  max:  1420  avg:  1418   | batched:     0
verts #>       min:  1082  max:  1084  avg:  1082   | batched:     0
player-detail> physx:  0.4 animation:  0.0 culling  0.1 skinning:  0.0 batching:  0.0 render:  6.3 fixed-update-count: 0 .. 1
mono-scripts>  update:  0.6   fixedUpdate:  0.6 coroutines:  0.0 
mono-memory>   used heap: 262144 allocated heap: 356352  max number of collections: 1 collection total duration:  2.3

shadowman,

are you using any OnGUI() functions for your HUD or any FixedUpdate() functions. I believe they can take a big hit on performance.

I am using many on GUI, and many FixedUpdate (one for each spaceship) but the point is that, once I disable on GUI functions to test the performance, I get the same framerate.
Even more, I get 30FPS on splash screens that only have a GUI texture on it. So may be limited by software, I guess what I need now is to test the app in slower devices to see the performance drop during gameplay.

Sorry if I’m hijacking a thread. :sweat_smile:

BUT! As for the original question of comparing tag with a string. I’ve been trying to get away from strings but not having a lot of luck

Is there any other way to compare a tag? Can a tag be compared to an enum and would it be any faster?

What other strategies can be used

this hijack is allowed xD
I don’t know how to avoid tags, but are you sure is your performance problem? I have seen no difference, and my player prefab and every spaceship y instantiate have many tag checkings.

is it possible to get from a collider it’s rigidbody mass?
if so, for damages I could use the mass of the collider, and not the tag, to set the effects.
This, in case of course, it consumes less resources than using “tags”.

well, so I have tested the game on iPhone2G.
The average FPS is around 18FPS, and can drop to 6FPS. Unplayable (not to say the graphic glitches that may appear).

So, I need to keep optimizing. The problem is that no matter what I do with textures and models, I keep getting the same framerate, even with empty screen (only player and skybox).

So the player code must be the problem!

accoring to profiler stats you posted you’re stable 30 FPS.

If you have occasional framerate dips, then you should look at the profiler stats exactly at that moment. You should be profiling on the slowest device too.

according to profiler stats you posted you’re stable 30 FPS.

If you have occasional framerate dips, then you should look at the profiler stats exactly at that moment. You should be profiling on the slowest device too.

Couple of things I would recommend checking or thinking about:

  1. You mention you are using lighting. Is that really necessary? If you can achieve the same look with a self-illum shader, that will cut your draw calls and increase performance.

  2. Are you using mesh colliders on your game objects? If so, look at swtiching them to box colliders wherever possible. Collision detection with mesh colliders is very expensive compared to mesh colliders. Especially if you have a lot of them in play at the same time.

  3. Use trigger colliders wherever you can rather than regular colliders. This is less expensive.

  4. Check the import settings on all textures and make sure that you have set the max size to the smallest size you can get away with and still achieve the look you want ant that they are compressed. You don’t mention what shader you are using, but if you stick with a light, then take a look at different shaders from a performance standpoint.

  5. I see that you are not running any animations, which prompts me to ask whether you are creating any sprite animations through UV index manipulation. If you do, make sure you are accessing the textures through the shared material attribute, not the material attribute, as doing the later causes duplicates to be created. Also, if you are doing any animations this way, take a look at using a single texture atlas, as opposed to individual textures, if you aren’t already doing so.

  6. And then finally take a look at your scripts themselves. There are dozens and dozens of threads here on script optimization. You should read them and make sure you are following best practices. The big killers of performance are declaring variables inside your update function/method, and continually looking up object references therein. Also, take a look at whether there are things being done in each update that could be done in a coroutine with a lower frequency, than every frame.

By default the kFPS value (in AppController.mm) is set to 30, so that would explain why you are stuck at 30 on the 3Gs.

I can’t really see why you’d be stuck at 15 on a 2G, except in your video I noticed that the explosions are layered alpha transparencies and can cover up to a 3rd of the screen.

You might want to change your explosion effect so that it is one texture animation that looks similar to the particle system.

thank you for your advices mates.

to HanulTech:

  1. I use lighting, and desabling it I saw no performance difference in 3GS. But I saw a nice improvement on 2G! may make the game playable with a bit of work!

  2. No mesh colliders. Only box and sphere.

  3. I will use triggers, thanks for the suggestion.

  4. All textures are undder control, I’ve been trying even crazy useless compresion to check if there was a difference. 2G showed nearly same framerate.

  5. no animations, nowhere

  6. I aim trying to optimize my code, but as we have seen here, I have nothing to lag my game. I have now less than 5000 triangles, less than 20 drawcalls and less than 1.5MB of textures…

the problem here is that I spected more performance on “old” iPhones.
I noticed an important performance drop (about 4-5 FPS) when the player is shooting.
Here are the profilers for the 2G generation:

empty screen, only player and background:

iPhone Unity internal profiler stats:
cpu-player>    min: 27.6   max: 41.6   avg: 33.8
cpu-ogles-drv> min:  1.8   max:  6.5   avg:  3.0
cpu-present>   min:  1.2   max:  7.9   avg:  2.4
frametime>     min: 35.5   max: 97.4   avg: 45.9
draw-call #>   min:  17    max:  18    avg:  17     | batched:     0
tris #>        min:   871  max:  2342  avg:  1206   | batched:     0
verts #>       min:   661  max:  1524  avg:   854   | batched:     0
player-detail> physx:  3.6 animation:  0.0 culling  0.6 skinning:  0.0 batching:  0.0 render: 16.5 fixed-update-count: 1 .. 3
mono-scripts>  update:  7.0   fixedUpdate:  4.5 coroutines:  0.1 
mono-memory>   used heap: 356352 allocated heap: 356352  max number of collections: 0 collection total duration:  0.0

now, gameplay and shooting, down to 10fps (the player can get 4-5 shoots on screen, all batched, no texture, 8 triangles, 1 box collider, really simple script to autodestroy and set speed)

iPhone Unity internal profiler stats:
cpu-player>    min: 49.2   max: 94.6   avg: 66.8
cpu-ogles-drv> min:  2.9   max: 10.6   avg:  4.8
cpu-present>   min:  1.5   max:  4.7   avg:  2.2
frametime>     min: 63.1   max: 117.8   avg: 83.2
draw-call #>   min:  20    max:  24    avg:  22     | batched:     7
tris #>        min:  2189  max:  4059  avg:  3570   | batched:  1381
verts #>       min:  1303  max:  2282  avg:  2053   | batched:   582
player-detail> physx: 11.2 animation:  0.0 culling  0.9 skinning:  0.0 batching:  0.5 render: 20.5 fixed-update-count: 2 .. 4
mono-scripts>  update: 15.8   fixedUpdate:  4.6 coroutines:  2.5 
mono-memory>   used heap: 327680 allocated heap: 356352  max number of collections: 1 collection total duration:  7.0

now normal gameplay (spaceships and asteroids) but not shooting:

cpu-player>    min: 34.1   max: 62.3   avg: 48.2
cpu-ogles-drv> min:  2.2   max: 10.6   avg:  3.6
cpu-present>   min:  1.3   max:  5.3   avg:  2.0
frametime>     min: 43.3   max: 79.9   avg: 59.2
draw-call #>   min:  18    max:  19    avg:  18     | batched:     2
tris #>        min:  1415  max:  2308  avg:  1701   | batched:   622
verts #>       min:   883  max:  1287  avg:  1042   | batched:   256
player-detail> physx:  8.8 animation:  0.0 culling  0.4 skinning:  0.0 batching:  0.2 render: 17.9 fixed-update-count: 1 .. 3
mono-scripts>  update: 14.5   fixedUpdate:  3.1 coroutines:  1.4 
mono-memory>   used heap: 282624 allocated heap: 356352  max number of collections: 1 collection total duration:  6.9

I replaced all “collisions” for “triggers” when I could, and disabled the lighting :cry: so now it is playable on old generations.
I set the max gameobjects lower as well, so the hardware is not collapsed.

Would you recommend to make special levels for 3GS so users can see better graphics?
I guess I can detect the generation and make the game change automatically the level to run.

Another thing you might want to consider is not instantiating and destroying your projectiles. Instead have a fixed set which are created and deactivated at scene load time. At runtime, instead of instantiating and destroying new instances, activate, animate and deactivate the pre-existing projectiles. I’ve found this can give a pretty decent performance gain on 1 and 2G phones. Of course, its complicates your game code considerably. And you can do the same with your particle emitters/renderer. Creating those and destroying them on the fly is not cheap on any device, but they seem particularly hard on the 1 and 2G phones. Probably the next thing to consider is dropping your particle system, partially or fully, in exchange for animated textures, which can be made to look very good with some work.