October 17, 2017 at 13:27 #22202arekusuParticipant
I’ve finally been able to start a little prototype project to try out Apex Steer ( bought it a while ago). I’ve been having a lot of fun. Things are easy to use and I was up and running with large formations navigating around obstacles in a couple of hours. Great work guys
I’ve reached the point where I want to push a lot of units on screen at once (the game is about decimating large formations of soldiers as a single absurdly powerful wizard) and I’ve been running into some performance problems. With 180 units moving in formation, I’m seeing just over 10 KB of garbage generated every frame, which seems to make an otherwise empty scene drop below 60fps.
Unity’s deep profiler points to 2 places In apex where the garbage is being generated: The first is when Steer for Formation calls DefaultSteeringTransientUnitGroup.GetFormationPosition(). In that case, it looks like the culprit could be when that method returns a struct assigned to an interface reference, which I think requires that the value type be boxed.
The other is when the load balancer calls VectorFieldManagerComponent.CreateVectorField(). As far as I can tell, all vector field implementations have comparable amounts of garbage generation.
Is my setup of the formation components incorrect? It seems strange that create vector field is called every frame. I started out basing things on one of the example scenes. I can send a stripped-down reproduction case if needed.
Thanks for your time, and thanks for making a cool plug-in. Really want to see hundreds of guys on screen at once without performance problems
October 18, 2017 at 12:03 #22211GeminiorKeymaster
- This topic was modified 3 months ago by arekusu.
You are correct that DefaultSteeringTransientUnitGroup.GetFormationPosition() does result in boxing a struct. It will take quite a few calls per frame to reach 10k though, one call being around 20 bytes worth of garbage.
Apex Path in particular and Apex Steer to a large extent as well, were made to be generic and extensible.
This does come at a cost though, which is why I would always recommend using them as a foundation and then specialize them to fit your needs.
In this case you can simply change the return type to be the Position type or with a tad more work to be a Vector3.
The vector field is a different story. A vector field is only created the first time a group receives a path.
When/if the group issues a new path request the vector field is updated rather than recreated. Either way the previous field is garbage.
If this happens every frame it would mean that you reform groups every frame and issue a path request / manually give them a path.
Only reissue path request when needed and at most every ½ second and only reform groups when needed. You can add and remove members of existing groups.
You must be logged in to reply to this topic.