Any tips on making shuriken faster? If I add about 50 emitters to my scene my framerate drops by 1000 fps. It doesn’t seem to matter how many particles are being emitted, the hit is bad no matter what. I know I shouldn’t worry about performance until its under 60fps, but other than the particles and a couple simple meshes my scene is bare bones and I still have to add things like trees, enemies, etc.
All of my searching has basically turned up “use legacy” as the answer, but legacy doesn’t seem to have the same functionality that I need.
Firstly, which version of Unity? There probably is a reason why people all suggest “Legacy;” it’s because shuriken offers more functionality, but can be a bit of a hit on performance CPU-wise, as there is more going on in the engine’s code when using that. I recommend not using too many emitters at once. If such a case is unavoidable, then at least use a script to turn them off if 1: they’re not going to affect gameplay much. and 2: they’re outside the rendering viewport.
Example case: there is a small fire in the scene. other than being a lovely fire, it isn’t really used for anything gameplay-wise, so let’s turn it off should the camera not see it.
On top of that, it also looks like a LOT of things are being dynamically batched, of which can drag down performance too. See what happens if you turn dynamic batching off; If there’s a speed increase, there’s one of your bottlenecks…
I know, that’s why I’m worried. I haven’t actually added any functionality yet. The only thing in the scene is a couple of meshes and the particle systems. I’m worried that by the time I get to my functionality, the fps will suffer.
I probably won’t actually have 50 particle systems in my scene, this was just a test. I was just wondering if there was anything to do to make it perform better.
I have them all attached to game objects. What’s the best way to disable those game objects if they are occluded or out of the camera?
I ended up doing this, would this be a good way to do it? Just disabling the game object didn’t seem to disable the particles so I had to disable each particle on the object.
void OnBecameInvisible()
{
foreach(var p in GetComponentsInChildren<ParticleSystem>())
{
p.enableEmission = false;
}
enabled = false;
}
void OnBecameVisible()
{
foreach (var p in GetComponentsInChildren<ParticleSystem>())
{
p.enableEmission = true;
}
enabled = true;
}
Yeah, had I lost 500fps I probably wouldn’t have cared. When it dropped to 90 from 1500 I got a little worried. People say not to optimize until its a problem, but the problem with that mentality is that when its time to optimize you have way to much to optimize. If you keep everything as tight as possible from the beginning then you have less to worry about later on. That thinking is an artifact of my day job where I have to analyze sql reads on just about every query we write because one bad query that runs thousands of times a minute can really ruin database performance. Optimizing after the fact costs an order of magnitude more than it does if you do it up front because of the lost efficiency that users experience, plus the mad scramble to fix the query on the fly.
I believe in optimizing early and often. I usually plan to dedicate 20% of my time on any given project to performance optimization. Modern computers are quite powerful, but that shouldn’t give programmers a license to write bad code. Back in the day, clock cycles mattered, and I guess I’m still stuck in the past in that respect.
It’s the same for complex art assets as well. Imagine having a super complex character with multiple animated (timed) elements, a complete back pack full of interchangeable weapons and in game magic fx linked to the animation sequences or actions/triggers, look at constrains, IK hooks, a complete durable blend tree - then realize there are too many draw calls for one character and there needs to be resolution reduction to the entire thing. That would suck!
at that time the camera was the most, but that’s just the screenshot I got. Most of the time it was the Particle system. The profiler doesn’t really give all that much info other than Particles and Camera are taking a lot of time. What more can I do with that information?
You want Time MS. Click that column to sort by it, so highest Time Ms is at the top. That’s all. Everything else doesn’t matter. That bad boy right there is what you want, as % is just for curiosity value really.
3.93 ms on 50 emitters … are they spawning? if so you’re looking at pretty large amounts of particles being updated?
Yeah, that’s what I thought too. It seemed high for a small number of emitters. Each emitter has a max of 500 particles, emitting 100 at a time. They have collision and gravity enabled. There are no sub-emitters. Even if I turn off all of my options and set it to 1 max particles, it still take a lot of time.
Yeah, I don’t know. Like I said, performance is still bad if I limit max particles to 1 or disable collision. I’m going to redo this as a mesh with scrolling uvs and hope I can get a similar look. Though making meshes takes me a long time since I’m not an artist.
One important thing to learn when looking at performance is that framerate is not linear. What is important is how many milliseconds things take. Back to that at the end.
What I noticed from your profiler screenshot: those 50 particle systems were costing around 4ms, and the camera rendering about the same. Seems quite reasonable if we are talking 50 BIG particle systems all affected by collisions.
(50 * 500 particles = 25k particles to work on!) If these particles are of any reasonable size on the screen the overdraw caused by them will also not be negligible, and would explain the 4ms spent by the camera.
Around 8ms for a particle stress test, leaving 8ms for a 60fps game, and 24ms for a 30fps game, sounds somewhat reasonable to me.
Also dont forget to fold out the info about what IN the particle stuff is costing so much!
Going from 30 fps to 60 fps means going from a budge of 33ms/frame to 16ms/frame, to get a framerate of 120 fps you get as little as 8ms/frame, 240 fps is then 4ms/frame. At what point it becomes really pointless! (In other words, going from 120 fps to 60 makes a LOT of difference in how much you have time to do! As the time to do something is constant, no matter how many fps you save/loose. The change in FPS depends on what the sum is.)
Shuriken is eating CPU power even if you just have it on your scene. I have written a Shuriken optimization guide for Unity 3.5.7f but it still applies for 5.0
Wow varfare, that’s an interesting write up, particularly regarding the overhead on inactive shuriken systems.
Currently I disable the entire gameobject containing the shuriken component when it’s not needed, are you saying it will still eat performance more than a normal inactive gameobject?