Hello, !
I am working on “Our Ghosts of War” (link here) and I want to use this kit to implement vehicles. Right now, I am focusing on tanks. I have set up a model of the Tiger I and physics are working great. Before integrating this into the project I have been testing performance and noticed that placing several of my tanks (10 in my case) has a significant drop on the FPS so I tried doing some optimisations, which you might be interested in. I managed to double the FPS, which sounds good but I wish I could further improve it. My tank is set up nearly the same as the M113 with the only differences being: 1. three additional wheels on each side 2. spline tracks were replaced with a skinned posable mesh whose bones are aligned with the wheels and moved up to make the tracks follow the wheels 3. the tracks movement is animated using UV animations. For debugging, I have added afunctionality which causes the tank to keep driving forward, so it does not go to sleep while debugging. All optimisations were run separetly for better analysis.
The simplest optimisation which works but yields only minimal improvements: For both tick functions, the main tick and the substepping tick function, I added added the option to configure that some ticks are simply skipped. For instance, I tried several configurations in which every 2nd, 3rd, etc up to 8th tick are skipped. Setting it too low causes the simulation too look jerky but setting it too high will hardly yield any performance boosts. Empircally I determined that without loss of the simulation quality skipping every 5th tick is fine. However, it turns out this hardly saves much performance, as might have been expected: With 10 tanks, it went from ~18 FPS to ~21 FPS so a rather small improvement but it still works.
A second improvement is in the main tick: there are several animation functions which only need to be run when the client is close-by to a tank. I set a configurable property that ensures the animation functions AnimateWheels, AnimateTreadsMaterial, AnimateTreadsSpline, etc. are run only if the client (in both standalone and networked games) is close-by, say 50 meters. This made the FPS go up from ~18 FPS to around ~36 FPS when the client went a little away. I think this optimisation is quite useful as usually at around 50 meters distance it is quite difficult to see the wheels spin anyways; after some gameplay testing I can confirm this: you do not notice it at all so the quality is not harmed in any way. So it seens a good idea to do distance based animations.
A third optimisation I tried is quite similar to the second approach; it works with occlusion culling. Before executing animations, it determines whether a tank is actually visible to the client. If it is not, we need not bother playing the animations. This yields a significant boost similar to the one in the second approach, optimally performing when you can only see your own tank. The performace then increases to ~35 FPS, again with 10 tanks. So it appears this optimisation is also a good idea.
The profiler has also told me that CheckWheelCollision and ApplyDriveForceAndGetFrictionForceOnSide are quite more expensive that the other ones all together. Reason for this is because those functions are run multiple times for every wheel and suspension. I tried minimising calling those functions using distance culling again. However, this yields quite funny behaviour. If I spawn my tank far away from them (>50 meters which is the configured culling value) my FPS is 120 for my tank on its own (awesome!), however if I drive to the other tanks they yield to simulate: the wheels are stuck in the floor. Once I ram them, they start to drive around until I exit the 50 meter sphere and they yield doing their phyiscs again. Now I admit what I tried was very adhoc and I have not tried all options yet, nor have I shared my setup with you yet, but maybe you have an idea to prevent those expensive function calls?
Also, do you have any other ideas to optimise vehicles both on client and on server? In our current game, their may be up to 100 tanks which are concurrently active, which would be quite expensive for the server. Of course, the server never has to run those animations and some of the physics code but it appears as soon as I do not run one of the physics functions handling movement, the tanks starting behaving in a weird manner. What are you plans for performance updates to the project?
As a side, I will continue on working on these optimisations and add them to the project as I have the time to do so.