I have created a custom controller for my units and now I would like to use the NavMesh system to provide a path to those units.
I do not want to simply use the NavMeshAgent system to move the unit because I need more functionality than that. Like for example, falling in holes or flying which would not be on the areas of the navmesh.
How can I get the path that my unit needs to follow to a certain destination from the NavMeshAgent? I would then use this path to know about the movement I must do every frame. This path needs to be updated if obstacles are blocking the way.
CustomController.Move(Vector3 _movement);
Flying is easy to implement with navmesh by just adding vertical offset to the agent and it also allows to make certain areas of your level (border, for example) non-flyable. However if you want custom movement, you just get path from navmesh using Unity - Scripting API: AI.NavMesh.CalculatePath
1 Like
And when you get this path, how do you get the next frame’s movement from it?
Like you would do with any way point system, it’s just a list of ordered points. Unity - Scripting API: NavMeshPath
Ie:
- find closest corner (first on the list?)
- find direction toward the closest corner,
- check the distance to the corner
- if close and last point, then stop
- if close to point, then set next point
- else move toward*stepLength
- loop
Yes I did this but I realized that despite following the path correctly I had problems with NavMeshAgent not being exactly where my controller is. This was due to my controller moving slightly differently from the NavMeshAgent.
Setting NavMeshAgent.updatePosition = false is a necessity for moving with a custom controller.
I tried a lot of different methods by warping or sampling the path but the best one by far is the one proposed on this page of the forum by a unity dev:
https://discussions.unity.com/t/559089
using UnityEngine;
public class MoveRigidbody : MonoBehaviour {
Rigidbody rb;
NavMeshAgent ag;
void Start () {
rb = GetComponent<Rigidbody>();
ag = GetComponent<NavMeshAgent>();
// Disable agent control of the transform
ag.updatePosition = false;
ag.updateRotation = false;
}
void Update () {
// Move rigibody by agent velocity and update agent position
rb.velocity = ag.velocity;
ag.nextPosition = rb.position;
}
}
2 Likes
Oh yeah I always avoid that part of the system, it annoys me. Sorry.