I have a use case where I have to add dynamic obstacles to the navigation mesh created with RecastJSPlugin. Are there any examples how to tackle such a problem?
In my case the obstacles are, for example, Star Trek style doors that can be closed and therefore should block the agents from going through them.
@Cedric will know if there are better ways to do this built in right now, but one way you could handle this would be to have different nav meshes depending on whether the individual doors are open or closed. That may not be ideal, though, because if you have a lot of doors that can operate independently, the number of nav meshes you’d need quickly becomes a combinatorial explosion. If you wanted to address it all on the same nav mesh, you’d need to be able to manipulate the cost of visiting certain nodes in the graph generated from your nav mesh and used by A*, but there are some things to consider with that:
- If your agents were already moving when the doors closed, you’d need to tell them all to recalculate their routes in case they were affected.
- From a quick look at the A* implementation, I don’t see a way to dynamically modify the costs used internally, so that would either need to be hacked or added in.
- If there’s no other route to get to where they’re going and all you’ve done is increase the cost of passing through a certain area, A* will still find a path that leads through that area, effectively telling your agents to phase through the door if there’s no other option. If you want to prevent that, you’d either need to use a non-cost-based approach or have a thresholding mechanism to be able to cancel movement altogether if it’s too costly.
Sorry I don’t have a simpler answer for you, but if there’s a straightforward way of doing this with the features that are currently built in, I’m not aware of it. Hope this helps, and best of luck!
I suppose there is another option – a bit manual, but I think it should work. Instead of having a single nav mesh for the whole area, you could have individual nav meshes for each room. If your agent’s destination is in the same room, use navigation results directly; but if the destination is in another room, instead of trying to find your way to the destination, just try to navigate to the appropriate door, then to the next door, etc. Note that this doesn’t really solve the problem so much as escalate it – you’ll still need to do something graph-search-like to figure out which rooms to go through. However, because that graph will be just a graph of doorways, it should be simpler to manage manually, and it will give you the freedom to ignore doorway options if the relevant doors are closed.
Thanks again @Cedric for all your great work
Yes this is just what I’ve been looking! Thank you @Cedric and also @syntheticmagus !
I have only one question left; in the playground demo, if the agent gets slammed by the doors, it can’t be moved again. Any idea what causes this?
I think I can improve that behavior but I’m a bit sceptical on the result. Agents might go thru the door or navmesh as it’s closing. As a work around, depending on your game design, I’d suggest to not allow closing door if a agent is in the range of the door. Or kill the agent if the door is closing when in door range.
I’m open to suggestions to improve the navigation.
Yeah it is a bit tricky to do I am sure of that… Here is what I accept to happen after the agent gets slammed by the door:
- Obstacle appears on the agent, swallowing it.
- Agent stops movement towards the target point (this is what currently happens).
- After the door is opened again, the agent is still alive and can be moved again.
However this is of course not something that should happen in the game; I assume that it should be somehow prevented that, for example, a player could not get stuck inside the door and should be allowed to pass through the door if they have already entered the obstacle zone. If it is not a player, but an enemy, I could easily murder the agent and it would be a fun game mechanic as well
How easy would these changes be to add to current plugin?
- If agent is stuck on obstacle, allow it to move after obstacle is removed (for robustness sake) BUT only with new crowd.agentGoto -call. So the previous path would be destroyed when agent is stopped by the obstacle.
- Add a boolean to agent that, if true, allows it to continue moving after it has gone inside the obstacle.
Sounds doable to me! I add a line on my todolist. I might be able to fix that this week.
Cool! I’m very eager to test the changes!
I’ve checked recast source and there is no automatic way to recover the agent once it’s outside the navmesh (trapped by an obstacle).
But, you can query the agent state ( ICrowd | Babylon.js Documentation )
When the agent is trapped, the state is 0. You can then, depending on your game: kill the agent, teleport to a new location, …
For performance reason, you can check agents when the navigation mesh changes (when an obstacle is added for removed).