- Home /
NavMeshAgent not fully reaching destination, thus it won't delete itself when it gets there
Hi guys,
I have some code that spawns a bunch of NavMeshAgents (they're cars with NavMeshAgent components) and sends them to destinations that are specified on the spawnpoints. Each car has the following code in its Update() function:
...
// Get new navpoint if previous target is reached
if (transform.position == target.transform.position || transform.position.z == target.transform.position.z -1 || transform.position.z == target.transform.position.z + 1 || transform.position == (target.transform.position - Vector3(1, 1, 1)) || transform.position == (target.transform.position - Vector3(-1, -1, -1)))
{
if(target.tag == "Car End Point")
{
Debug.Log("At endpoint, destory");
Destroy(this.gameObject);
NotificationCenter.DefaultCenter().PostNotification(this, "CarDeleted");
}
else
{
//Debug.Log("At navpoint, deciding where to go next...");
if (targetScript.connections.Length > 0)
{
var element : int = Random.Range(0, targetScript.connections.Length);
target = targetScript.connections[element];
//Debug.Log("Connection[" + element + "] chosen.");
GetComponent(NavMeshAgent).destination = target.transform.position;
}
else
{
GetComponent(NavMeshAgent).destination = target.transform.position + Vector3(30, 0, 0);
//Debug.Log("No connections found, proceeding straight as an arrow...");
}
}
}
...
I put the || operators because I wanted to make it remove my cars if they come within a 1m of their targets (because they all seem to stop moving when they get to a distance of less than 1m from their targets. The original if statement looked like this:
if (transform.position == target.transform.position)
How do I make my NavMeshAgents go all the way to their targets, and/or make them delete themselves if they get within 1m of their targets?
MachCUBED
Answer by burtonposey · Aug 18, 2012 at 04:59 AM
It's unlikely you're going to hit right on a point with your movement logic. Had this problem with a loader last night going from 0 to 1. It was at 0.9999.... for a while and wouldn't quite get there.
I've written something that's kinda psuedocode. I haven't really tested it, but this is essentially what you need to do for your checks. First off, use Vector3.Distance. It's there to help you. If that's below a threshold( hard coded to 1 in my example), then go to the next target position. If you're at the last position you needed to go to, you "DestroyImmediate(this.gameObject);"
Hope this helps. It's C#, which I strongly recommend you start working towards coding in all of the time.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MagnitudeTest : MonoBehaviour {
Vector3 currentTargetPos;
int posIndex = 0;
public List<Transform> positions = new List<Transform>();
void Awake() {
currentTargetPos = positions[posIndex].position;
}
//DO NOT keep using GetComponent, store a reference in your class
// Update is called once per frame
void Update () {
//your distance threshold should probably be smaller than 1 meter if you want them to not snap to this spot
if( Vector3.Distance(transform.position, currentTargetPos) <= 1 ) {
Debug.Log("We're at our desintation");
transform.position = currentTargetPos; //set to make sure it's actually at the destination instead of 1m off
++posIndex;
if( posIndex != positions.Count ) {
//assign next target as new endPos target, do all of this over again
currentTargetPos = positions[posIndex].position;
}
else {
//we're at the end destination for this GameObject
DestroyImmediate(this.gameObject);
}
}
else {
//do your movement logic towards your target however you wish
}
}
}
It seems to have fixed the problem, but I will have to do some further tests before marking your answer as the correct answer. Thanks for your help, here's the current code:
function Update () {
Debug.Log("Car update method called, position: x:" + transform.position.x + " y:" + transform.position.y + " z:" + transform.position.z); // $$anonymous$$ovement speed code if (!pooped) { if(speed < speedLimit) speed += accelerationRate; if(speed > speedLimit) speed = speedLimit; } else { if(speed < maxSpeed) speed += accelerationRate; if(speed > maxSpeed) speed = maxSpeed; }
//Debug.Log("Travelling at " + (speed * 3.6) + "km/h");
nav$$anonymous$$eshAgent.speed = speed; // Turn wheels leftFrontWheelTrans.Rotate(Vector3((speed / 3.6) Time.deltaTime, 0, 0)); rightFrontWheelTrans.Rotate(Vector3((speed / 3.6) Time.deltaTime, 0, 0)); leftRearWheelTrans.Rotate(Vector3((speed / 3.6) Time.deltaTime, 0, 0)); rightRearWheelTrans.Rotate(Vector3((speed / 3.6) Time.deltaTime, 0, 0)); // Get new navpoint if previous target is reached if( Vector3.Distance(transform.position, target.transform.position) <= 1) { Debug.Log("At target, correcting position"); transform.position = target.transform.position; } if (transform.position == target.transform.position) { if(target.tag == "Car End Point") { DeleteCar(); } else { //Debug.Log("At navpoint, deciding where to go next..."); if (targetScript.connections.Length > 0) { var element : int = Random.Range(0, targetScript.connections.Length); target = targetScript.connections[element]; //Debug.Log("Connection[" + element + "] chosen."); nav$$anonymous$$eshAgent.destination = target.transform.position; } else { nav$$anonymous$$eshAgent.destination = target.transform.position + Vector3(30, 0, 0); //Debug.Log("No connections found, proceeding straight as an arrow..."); } } } oldPos = transform.position; }
Your answer
Follow this Question
Related Questions
NavMeshAgent Rotate With Model 0 Answers
Is there a way to limit the size of a navmesh? 0 Answers
Allow navmesh agents to be pushed off navmesh 1 Answer
My navmesh agent doesnt look at my player 0 Answers
Navmesh agent forward movement 1 Answer