Hello everyone. I want to ask for help. You see, I’m working in a “click-to-move” type of game, and I want my character to stop a few meters away from my “target object”. So I’m using a piece of code like this:
public NavMeshAgent playerAgent; public virtual void MoveToInteractuar(NavMeshAgent playerAgent) { this.playerAgent = playerAgent; playerAgent.stoppingDistance = 3f; playerAgent.SetDestination(this.transform.position); Interact(); }
My character actually stops a few steps before the target object, but a few seconds later it starts moving towards the target object. How do I prevent this from happening?
Thanks!
ps: My apologizes if I spell something wrong, english is not my native language.
Check out the most recent tutorial series on Adventure games on the unity learn site. They discuss this in the first two videos. What they seem to be doing is using the nav mesh agent for most of the movement but then within a certain distance they take over the movement and snap it to the desired location.
I’m still pretty new at c# and Unity, but I got this to work for me. However, my game is turn-based, so units have a set amount of distance they can move in a turn.
I click to move, then have the units automatically stop after they’ve gone the max distance allowed in a turn. I had the script calculate how long they’ve been moving and therefore how far they traveled, then had the movement shut down once it had gone as far as I wanted.
The stoppingDistance property set the range within the NavMesh stop the movement. As the manual saies, “It is seldom possible to land exactly at the target point”. If you need a more accurate positioning, you have to identify when the navigation of your character is stopped and then adjust the position as needed (remember to set isStopped to false for your NavMeshAgent… and also the enable property to false if the object continues to be too far away from your target).
You have to calibrate well the stoppingDistance property and “your more accurate distance” in order to get a better positioning.
See here.
You can use the remainingDistance property of NavMeshAgent to get the remaining distance from your target and compare this value with the stoppingDistance value:
void Update()
{
if (navMeshAgent.enabled)
{
bool bDistance = navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance;
if (!bDistance)
{
navMeshAgent.isStopped = true;
m_bFixPosition = Vector3.Distance(navMeshAgent.nextPosition, target.position) > distance;
if (m_bFixPosition)
navMeshAgent.enabled = false;
}
else
{
m_bFixPosition = false;
navMeshAgent.isStopped = false;
navMeshAgent.SetDestination(target.position);
}
}
}
...
// In an another method, for example OnAnimatorMove()
void OnAnimatorMove()
{
if (m_bFixPosition)
{
if (Vector3.Distance(m_Rigidbody.position, target.position) > distance)
m_Rigidbody.MovePosition(Vector3.Lerp(m_Rigidbody.position, target.position, Time.deltaTime));
else
{
m_bFixPosition = false;
navMeshAgent.enabled = true;
}
}
}
I just recently started to make a resource gathering game and decided to use NavMesh for handling the AI with State Machine pattern implement by myself for handling the units movement. With a lot of movement here and there with my attacking units I ran into this problem. I did some tests but didn’t debug anything yet and I found that is certain that Agent.SetDestination does not work correctly with Agent.stoppingDistance. I’m certain that I’m changing the variables in the correct order but the movement does not work as desired. Making your own movement with Aget.Move guarantees that the agent will stop at the given distance.
public IEnumerator MoveTo(Vector3 position) {
// move step by step until reaches the distance
while (Vector3.Distance(transform.position, position) > stoppingDistance) {
Vector3 _dir = (position - transform.position).normalized;
agent.Move(_dir * Attacker.speed * Time.deltaTime);
yield return new WaitForEndOfFrame();
}
}
I am facing this issue when using Agent.SetDestination. But using your fix worked, thanks!
I can see that, for example, when the agent.remainingDistance is 10 and the agent.stoppingDistance is 1, somehow agent.remaingDistance is less than agent.stoppingDistance.