Context:
In my RTS prototype, I am doing my best to ensure that I keep as much state as possible server authoritative using a Simulator, but I am running into some lag/performance issues, which I suspect could be related to shoehorning in state bindings where I could. This is making me re-think how my entities are set up, and I am starting with the movement mechanics used by the individual RTS units.
What I’ve tried:
Currently, I have a navmesh on the map paired with navmeshagents on the individual units. When the client wants to “move” a unit, it sends a command to the sync which when received on the simulator, updates the destination property for the agent, causing the agent to move on the simulator. I paired this with a naive approach to bind the unit’s position and rotation properties as replicated fields. This worked initially for seeing a unit move but fell short with missing walk/run animations. Before adding Coherence, I used a component on my unit to observe the velocity of the navmesh agent and update a float value on my animation controller on each Update()
. This then controlled a blend between idle, walk, & run.
To overcome the velocity no longer being present on the local navmeshagent, I next tried adding the velocity property to be a bound replicated value. This solved my problem, and the animation controller now correctly moves through its blended states, but I question if this was the best approach.
The question:
How is Coherence commonly paired with entities using navmeshagents & an authoritative Simulator?
I could see a few approaches:
- Only run the navmesh & agent on the simulator, and replicate all resulting values (position, rotation, etc.)
- Run the navmesh & agent on the client and simulator, and keep the “destination” property of the agent sync’d
I believe the second approach would work better, but I question if updating the agent’s destination is “valid” if the intent is for full server authority.