- Home /
Optimising for large groups of enemies
Hey guys, so I'm working on a game where there's going to be many enemies on screen at once, perhaps up to 30 at once. Each of these enemies may possibly be using pathfinding etc. Currently I have all of the enemies being spawned when the level starts, in total there could technically be between 0-320 enemies in the level at once. Obviously this seems to be getting extremely computationally heavy and the frame rate can slow down quite substantially even on my fairly good spec PC. So I'm wondering, what are some routes I can go about optimising this situation? Do objects not on screen get rendered or can I prevent that myself if they're not? Should I create NPC spawners that spawn the enemies when the player gets so close, and then de-spawns and saves the stats of the enemies when the player is too far away? Are there flocking methods like a boids group or something that would work well with pathfinding? I realise this question is somewhat broad, but I'm just finding it hard to know where to start.
Answer by PrimeDerektive · Sep 13, 2011 at 04:42 PM
Should I create NPC spawners that spawn the enemies when the player gets so close, and then de-spawns and saves the stats of the enemies when the player is too far away?
Absolutely. While they won't be rendered if they're not in the camera frustrum... they'll still run all their scripts (eg: pathfinding, calculating distances between itself and the player, whatever else your AI is doing). That making them only spawn when within range should help your performance significantly.
Also, make sure you're using Rigidbodies, not CharacterControllers. In tests with 32 animated models with simple AI my performance tests have meant a difference of 300+ FPS and 40 FPS.
As for Boids/Flocking, there are lots of solutions out there, difficult to know how they'd integrate with your pathfinding without knowing what you're using, though. Off the top of my head, there's one on the unify wiki, and of course UnitySteer, for starters.
Thanks a lot man, I didn't realise Rigidbodies were less expensive, the tutorials said you should always use charactercontrollers for humanoids, so I assumed it was the other way around.
Though that creates another question, I'm using the free version of unity, does pro provide anything that would assist this? For example does it only not render within the frustrum in pro or anything like that?
Nope... frustrum culling is automatic in all versions of Unity. You can tell by opening up your stats pane and watching your draw calls change.
rather than make a new query about this, I thought I might as well expand this comment section, I've changed them from character controllers to rigidbodies, but I have a problem now that I'm finding the tweaking very difficult, they're either moving very little, or lightning fast, and they keep sliding, I suppose due to the way rigidbodies perpetuate motion in a body. Is there anyway to simplify them to a situation where they literally go straight in the direction they are looking, and that's it? So if they turn they don't slide, and they move at a good speed. It may be less realistic as such, but it just complicates the movement and combat, and the lack of realism isn't an issue.
Rigidbody.velocity = transform.forward*movementSpeed;
Set it in FixedUpdate. Don't be afraid to directly modify velocity. The docs say "this will lead to unrealistic physics simulation"... but that is exactly what you're going for (jumping immediately to a set speed in a given direction).
I had already tried just setting the velocity, but for some reason he still seems to be taking mass and drag into account regardless, with a movement speed of 2 he barely moves at all, and then moves ridiculously fast whilst in the air. There's also another issue now that I've started using spawners, as there's still 81 of them, each checking their distance from the player, how can I simplify that down? Would trigger collision boxes use less computation? Or should I just have one update in the level that checks the player's position and tells which spawns to activate and deactivate accordingly? Sorry I'm kinda dragging out the question here, perhaps I should put this in a new one.
Answer by RKSandswept · Jun 30, 2013 at 08:45 AM
Check things like line of sight only every nth frame and stagger which get updated. That evens out the load. For example use the fixed frame count modulo 32 and the entity id modulo 32.
Answer by RKSandswept · Jun 30, 2013 at 08:45 AM
Or keep a work queue fifo and do N ai cycles each frame.