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?
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
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.
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)
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)
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)
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.
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).
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:
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.
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.
Use trigger colliders wherever you can rather than regular colliders. This is less expensive.
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.
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.
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.
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!
No mesh colliders. Only box and sphere.
I will use triggers, thanks for the suggestion.
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.
no animations, nowhere
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:
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)
I replaced all “collisions” for “triggers” when I could, and disabled the lighting 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.