I have read a lot of threads on this topic, but didn’t find a solution. I am using the NM agent to draw the path and the Character Controller to move with NPC (using the Move method), but the nav mesh agents are not avoiding other nav mesh agents, do you have any idea how to do that?
I myself have been trying to find an answer to this question.
How exactly are you using the Move method?
A solution I currently have but want to abandon is a custom A* path finding setup. Basically it exposes the f and h costs and allow you to modify it during update. So as my agents move across my nav grid they alter the h and f cost in a given radius. The player agent will then adjust its path according per frame to try and avoid other agents.
A similar solution with Unity’s nav would be to modify the nave mesh cost with a volume modifier attaches to the other agent and then re bake/ re path per frame. ( I’m a noob at unity navigation so this suggests might not be possible or very expensive)
Let me know if you find a solution and I’ll let you know what I find. My custom solution is extremely difficult to implement and to maintain hence why I’m looking for something off the shelf.
I am using something like this, except I forgot that I got rid of the Move function I am using root motion for that
My solution for now is to implement a custom AI Behaviour, since my game is open world and there isn’t a big chance 2 of the NPCs to walk in the same direction, I just stop one of the NPCs if that happens and disable the navmesh agent and enable navmesh obstacle (Set to carve, only on static = false), the walking NPC avoids the static one and after 3-4 seconds I disable the NM obstacle and enable the NM agent then continue it’s walking routine. It’s not the best solution, especially for games where you have lots of NPCs in a small area.
If you have lots of NPCs you can have a charactermanager class that handles figuring out where in proximity other characters are to each other, sadly I don’t have the code for that it’s just a suggestion a friend of mine uses in his game with lots of NPC walking in a small area.
I also don’t know if the NM agents built in avoidance isn’t working for me, because of the character controller or because it’s not working at all. My player has a navmesh obstacle component attached and the same NPC avoids the player, but won’t avoid other NPCs that only have NM agent.
THis is very specific to this developers game, i would not recommend OP uses this method. Just use NM obstacles on your agents and itll sort your problem out.
You can’t have NM obstacle and NM agent active at the same time. Adding NavMeshObstacles to my scene I had weird things with agents walking in circles or just walking into a wall over and over.
Yes but your not using the agent constantly every frame are you? Very inefficient.
Just use the agent to get a path, store that path, calculate any direction changes along that path.
Now move the agent along it with the navmesh agent TURNED OFF. and turn the obtacle on.
Effectively you only use the agent for 1 frame at a time.
I do this even when not using obstacles as NM agents are very heavy.
C# job system coming soon will rectify this.
Also try calculating the directional turns in the path asynchronously for better performance.
EDIT: to make more clear, effectively you just use the agent to calculate pathing. But you actually do all the moving, and facing direction yourself using the precalculated path. Using this method you can have 10000+ dynamic agents.
I’m at work at the moment but i can definately setup a small public bitbucket repo when I get home.
The code for working out turns along a path is generic and can be found on a variety of places, unity specific and not. I think there is even one on the unity wiki (if the wiki is not down again)
use that code to work out where all the turns are. Then use basic direction vector math to get direction to first “waypoint” (corner) and then each time you get to the next corner, change direction.
Very very very simply once you think about it, and means you can turn off the agents except at path generation.
If your still struggling ill put a repo up this evening when im home
EDIT: NavMeshPath.GetCornersNonAlloc for a non allocating version
Any idea about the performance on large terrains and multiple NPCs? I’ve heard bad things about having an obstacle that has Carve and is not set to carve only on stationary, basically its always making holes in the navmesh as it’s moving.
If you are still looking at this Daemonhahn, I would very much like an example of how to implement this. I understand conceptually, but I am too new to Unity to have a good idea of how to go about an implementation. Thanks!
Hey, I am at work at the moment, but will try and write you a snippet when I am free
EDIT:
Public NavMeshPath pathToUse;
public Queue<Vector3> cornerQueue;
public Vector3 currentDestination;
bool hasPath;
public float currentDistance;
public float minDistanceArrived;
Vector3 direction;
public float moveSpeed;
void /// <summary>
/// Start is called on the frame when a script is enabled just before
/// any of the Update methods is called the first time.
/// </summary>
void Start()
{
SetupPath(pathToUse);
}
// get the corners and add them to a queue for use to use
void SetupPath(NavMeshPath path)
{
cornerQueue = new Queue<Vector3>();
foreach(Vector3 corner in path.corners)
{
cornersList.Enqueue(corner);
}
GetNextCorner();
currentDistance = (transform.position - currentDestination).sqrMagnitude;
hasPath = true;
}
// get the next corner, and set direction
void GetNextCorner()
{
if(cornerQueue.Length > 0)
{
currentDestination = cornerQueue.Dequeue();
previousCorner = previousCorner;
direction = transform.position - currentDestination;
hasPath = true;
}
else
{
hasPath = false;
}
}
// move towards the point
void MoveAlongPath()
{
if(hasPath)
{
currentDistance = (transform.position - currentDestination).sqrMagnitude;
if(currentDistance > minDistanceArrived)
{
transform.position += direction * moveSpeed * Time.deltaTime;
}
else
{
GetNextCorner();
}
}
}
// Update the agent
void Update()
{
MoveAlongPath();
}
That code is entirely untested but should work with little ammendments!
You set a minimum arrived distance to set how far a agent goes until it stops. You also need to set the movespeed and provide a navmesh path, but that will do the basics of what I was saying!
EDIT2: So what ive written will work out the path and move a navmesh agent along a path. Then all you need to do is either raycast from each agent towards their current destination and if these rays hit each other you know that agents will collide!
Or you could go through that queue (or use a list instead) of waypoints (corners) and fire rays Along each one (or place colliders) and then if theres collisions you know the paths intersect. theres literally so many ways to check intersections between lines, which when you boil it down is what your doing at this stage
LOL. Thank you very much for the thorough reply. It has been a while since I posted this question. I actually ended up deep diving into pathing and wrote my own navigation system using A* plus boid flocking.
@MadeFromPolygons_1 Isn’t the idea of having NavMeshObstacles on agents dangerous when it comes to raycasting on the navmesh? You’re going to create a lot of holes throughout the navmesh and the raycasts you will then do to find valid positions on the navmesh will be incorrect, right?