So I’m having some issues with performance with my RTS.
As soon as the soldiers start to move the performance tanks. Moving the camera around becomes sluggish and choppy. And after searching for a solution I haven’t found anything useful yet.
I’m using a Detour crowd controller, and my soldiers have a Character movement component. Movement is handled by a Behavior tree. And there’s about 100 of them.
I’ve tried adding unique collisions to lower the collision costs.
I’ve tried adding … eh… the object avoidance thing, RVO?
I’ve tried to set the pathfinding to Navmesh walking.
And then I ran into a thread that showed this debug tool. But I can’t really tell what it means. I guess the top two things take up a lot of performance though are only few in number… but what could they be? Is there a way to get more detail?
Don’t run navigation on every tick. Split it so you only do 5% of each moving character per frame, so that at 60 Hz, each character does navigation 3 times per second.
Note that “do navigation” and “keep moving” are different things – just have them keep moving in the previously determined direction, and only turn when they run the navigation tick.
Also, you seem to be doing a lot of things in Blueprint? If so, try doing less complex logic or loops in blueprints, and move that kind of behavior to C++. (It’s hard to tell, because the “blueprint time” may include code that then runs natively, but is called from the blueprint.)
How do I do this? Unreal is soo labyrinthian that I have no idea of where to start looking.
And yes, most of my logic is done in blueprints since I don’t have much programing knowledge. So moving over to C++ isn’t really an option at this point.
But I do need to optimize some of my checks. Not that any of them are very complex. Basically just keeping track of variables.
Are you using Behavior Trees or coding it in BP?
Either case, don’t use ticks.
Once the AI has picked its destination, it will update on its own navigation in the node until it reaches it.
Both.
I’m using blueprint script to get a location (mouse click for player controled units, and getting getting locations based on placed actors (named Tactical points) for the AI). When this location is set the Behavior tree runs and tell the units to move to that location.
And when you say “Don’t use ticks”, where should I not use ticks? On the Character move component? On the Unit? Or where?
Turning off the ticks on the Character movement component doesn’t seem to do the trick.
When we say “don’t do things in Tick(),” we mean “don’t implement the Tick event in blueprints, and don’t set the actor-ticks flag in C++.”
If your blueprints don’t actually implement anything on Tick(), then there’s nothing for you to remove.
If that is the case, then perhaps what you’re trying to do is more work than the current systems can do as-implemented, and you need to build better systems (presumably in C++.)
The pathfinding and RVO that’s implemented in Unreal Engine is mainly for sparsely populated NPCs, not for full divisions of RTS units. Think “Skyrim” not “Age of Empires.” Path finding is generally one of the main challenges of building good RTS game engines, so it wouldn’t surprise me if the default behaviors in Unreal just aren’t up to that particular task.
Maybe there’s still something going on in your code that you could fix, but it’s hard to tell from just a forum conversation – you’d probably need to pair up with an experienced developer to debug it for real.
Oh for anything. Gotcha. Could probably move most of the tick script to be more reactive instead.
Yes I’ve started to understand this that Unreal can’t do pathfinding at all
But since most of the complexity would be coming from the other soldiers since the navmesh is already built. Wouldn’t it simplify the pathfinding calculation if I somehow removed the collision between the soldiers?
I don’t think you can entirely remove the collision detection, because the character movement component needs it to stay on the ground and not walk through trees and such.
That being said – maybe the problem is that you have too many trees and such? Are they part of the walkable area? If you remove collision meshes from your trees, and instead just put large collider boxes around those areas, does the frame rate improve?
It’s hard to tell what else could be going on without a real performance deep-dive, though. Hence, “you should pair or contract with someone experienced if you want to go forward with this :-D”
But static meshes shouldn’t affect performance since the pathfinding should calculate from the baked navmesh. It’s only the other soldiers that are dynamic, but they don’t really affect the navmesh either. So that would only leave the collision detection between the soldiers due to the Detour crowd controller.
But yes, probably need to get hold of someone who is a bit more tech savvy when it comes to Unreal. Cause the engine is really cranky
You are probably deep diving into a complex project, but I like that.
We don’t have a lot of info to work with but I can give some tips based on what I see here.
I am pretty sure you are using Tick to check for certain conditions or to update conditions per frame. This is not recommended like the others said already. Instead you should take a look at how delegates / event dispatchers work.
What I mean by this is that there is a way to subscribe an object to another object to be notified when it does something, without having to check for it manually:
Another thing, you should reduce the amount of calculations needed where possible, especially if they run on tick. For Example, you can easily divide an RTS game into classes which manage the units for each team:
RTSTeamSubsystem:
- Holds teams of players and AIs playing the RTS
Team:
- List of its own units
- Holds all UnitSquads for this team
- Access to team logic
UnitSquad:
- Holds units within this squad (think of a commander, commanding tanks)
- Reacts to player commands and triggers.
- Acts as the main AI behind a set of units.
- Does formation and navigation logic, to avoid calculating this per unit.
Unit:
- Mindless Pawn controlled by its UnitSquad (like a hive mind), to avoid extra calculations.
- Simplified collision, optionally ignoring its own squad's collision or any Unit's collision.
- Does not execute its own AI?
The walkable area is calculated just once in the editor as long as it’s not configured to be dynamic. The collision complexity of any amount of trees will not make a difference here. You can ignore collision channels and entire actors as well per actor, so it is easy to set up characters with a default collision preset while also ignoring eachother as an actor.
Could you please try to use UNavMovementComponent rather than UCharacterMovementComponent? As your performance picture shows, Char Movement Total was very expensive. Because the UCharacterMovementComponent will keeping execute FindFloor method when Performing move. This is a sweep operator(GeomSweepSingle) based on scene query of physx, it is expensive.
In FPS and TPS games, the real player characters should use UCharacterMovementComponent because of the networking features such as Client Prediction and Server Reconcile and so forth. But in RTS games, the character is actual a AI agent. Pathfinding based on navmesh is the key point for moving. So I think UNavMovementComponent is enough.
@Roy_Wierer.Seda145 Yes I got something like that setup. Currently in the process of moving around a few functions so they are no longer par of ticks. So the Event discpatch might come in handy.
The only thing I can’t do is making the individual soldiers mindless drones, because I want to have some for of “personality” to each soldier. But most of that should still be rather cheap variable checks.
@yinpsoft Oh that sounds like a good change. I’ll have it a go!
Generally I’ve also been cutting down on all the tick calculations that I’ve been able to. Apparently my Overlap detection script caused most of the performance hit, So I’ll go back to UEs percception system and see if I can get it to work better than what it did when I first tried it.
Strangly the removal of these ticks scripts also affected the cost of Char Movement Total… I presume this is because there’s just more resources for it so it does’t have to wait as much.
Hello! I just wanted you to know that your advice has single handedly saved my entire project worth of 4 months of work! I don’t how to thank you, total lifesaver!
Also how to do this? I am using the AI move to node. Will I have to run a tick like function that gives a force to the characters inbetween the navigation cycles?