I'm working on an AI script in Unity 5 mostly constructed of coroutines to move around an AI object in my game. It actually works pretty well and is frame independent that way. I'm trying to avoid cluttering the Update
function of the class.
However, I'm trying to create a function called wander, where the AI hangs around and randomly chooses a couple of Vector3
s in the area of the waypoint and travel to each of them. After that the AI should go to the next waypoint and do the same thing into infinity basically. Collision detection and all that sort is for later parts. I want to get the navigating part fixed first.
void Start(){
agent = GetComponent<NavMeshAgent> ();
collisionRange = GetComponent<CapsuleCollider> ();
collisionRange.radius = detectionRadius;
if (waypoints.Length > 0) {
StartCoroutine (patrol ());
} else {
StartCoroutine (idle (idleTime));
}
}
IEnumerator patrol(){
agent.SetDestination(waypoints[waypointIndex].position);
Debug.Log ("Patrol started, moving to " + agent.destination);
while (agent.pathPending) {
Debug.Log ("not having path");
yield return null;
}
Debug.Log ("I have a path, distance is " + agent.remainingDistance);
while (float.Epsilon < agent.remainingDistance) {
//Debug.Log ("Moving...");
yield return null;
}
StartCoroutine (nextWaypoint ());
}
IEnumerator idle(int time){
Debug.Log ("Idleing for "+ time + " seconds");
agent.Stop ();
yield return new WaitForSeconds(time);
if(waypoints.Length > 2){
agent.Resume ();
StartCoroutine(patrol());
}
}
IEnumerator wander(){
agent.Stop ();
Debug.Log ("Going to look around here for a while.");
Vector3[] points = new Vector3[wanderPoints];
for (int i = 0; i < wanderPoints; i++) {
agent.Stop ();
Vector3 point = Random.insideUnitSphere * wanderRadius;
point.y = transform.position.y;
points [i] = point;
}
agent.ResetPath ();
agent.SetDestination(points[0]);
agent.Resume ();
Debug.Log ("point: " + points [0]);
Debug.Log ("Destination: " + agent.destination);
while (float.Epsilon < agent.remainingDistance) {
Debug.Log ("Moving...");
yield return null;
}
//StartCoroutine(patrol());
yield return null;
}
IEnumerator nextWaypoint(){
Debug.Log ("Arrived at my waypoint at " + transform.position);
if (waypointIndex < waypoints.Length -1) {
waypointIndex +=1;
} else {
waypointIndex = 0;
}
StartCoroutine(wander ());
yield return null;
}
If I swap the wander
function with the idle
function in nextWaypoint
, everything works as expected, but this bit will never work:
agent.ResetPath ();
agent.SetDestination(points[0]);
agent.Resume ();
Debug.Log ("point: " + points [0]);
Debug.Log ("Destination: " + agent.destination);
This is a bit of test code (manually setting only 1 position to go point[0]
, but it never will travel to that destination. SetDestination
will never get updated to the points I want to set them. I've tried calculating paths (NavMeshPath) up front and everything but the destination path will not change or reset weirdly enough. I've also had the while (float.Epsilon < agent.remainingDistance)
loop in the wander
function as well, but with no luck since it will remain in that loop forever since there's no path to go to.
I might be missing something here, or my logic is wrong in this case. Hopefully someone could give me a little push or maybe some extra debugging options, because I have no idea why the destination doesn't get updated in my wander function.