Waypoint system. Vector3 does not seem to update

I’m in the process of creating simple AI waypoints and have stumbled upon a problem Vector3 distance not being updated.

In the Start function I have a call to a Patrol function. I have created two waypoints and passed them to the AI.

function Patrol () {
	
		//Selects starting waypoint
		var curWayPoint = patrolPointA;
	
		while (true) {
			
			var waypointPosition = curWayPoint.transform.position;		
					
			//Enemy will rotate and walk towards next waypoint
			if (Vector3.Distance(waypointPosition, transform.position) < 0.1){
				if(curWayPoint == patrolPointA){
					print("B");
					curWayPoint = patrolPointB;
					waypointPosition = curWayPoint.transform.position;	
				}else{
					curWayPoint = patrolPointA;
					print("A");
					waypointPosition = curWayPoint.transform.position;	
				}
			}
						
			//Move to target
			//MoveToTarget(curWayPoint);	
			
			Debug.DrawLine(transform.position, waypointPosition, Color.yellow);

			MoveTowards(waypointPosition);

			yield;
		}
	}

I have two functions which I am experimenting with, one gets passed the vector position of the target the other, the actual transform of the target.

The below function receives the transform and works perfectly, but the character has no collision.

function MoveToTarget (targetPosition : Transform){ 

		//Rotate towards target position
		transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetPosition.position - transform.position), rotationSpeed * Time.deltaTime);     	 
		
		//Walk towards waypoint position
		transform.position += transform.forward * walkSpeed * Time.deltaTime;		

		animation.CrossFade("WalkForward", 0.3);
	}

The other function recieves the Vector3 position of the current target, but unlike the previous function the AI gets stuck rotating around the first target. For some reason the Vector3 isn’t being updated.

function MoveTowards (position : Vector3) {
	
		Debug.DrawLine(transform.position, position, Color.red);
		
		var direction = position - transform.position;
		
		// Rotate towards the target
		transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
		transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
	
		// Modify speed so we slow down when we are not facing the target
		var forward = transform.TransformDirection(Vector3.forward);
	
		// Move the character
		direction = forward * walkSpeed;
		GetComponent (CharacterController).SimpleMove(direction);
		
		animation.CrossFade("WalkForward", 0.3);
	}

The waypoint position is being updated, but either the function is broken somehow or the Vector3 position isn’t being updated correctly within the Patrol function.

There are two probably causes here. 1) You cannot rotate enough to get to the minimum distance of the MoveTowards funciton. 2) The MoveTowards function does not have any identifier stating that it has reached the target.

Now the odd thing is that both the Patrol and MoveToTarget should be based off of the MoveTowards function. Right now they are not…

Check out this rewrite:

var minimumDistance = 5.0;
var curWayPoint : int = 0;
var patrolPoints : Transform[];
var patrolLoops : boolean = false;
private var patrolDirection : int = 1;

// everything revolves around this:
function MoveTowards (position : Vector3) : boolean {
	// if we are inside of the distance just exit.
	if(Vector3.Distance(transform.position, position) < minimumDistance){
		Debug.DrawLine(transform.position, position, Color.green);
		return true;
	}
	
	// Rotate towards the target
	var rotation = transform.rotation;
	transform.LookAt(position);
	transform.rotation = Quaternion.Slerp(rotation, transform.rotation, rotationSpeed * Time.deltaTime);
	transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
	
	// Verify if we are facing the position
	if(Vector3.Dot(Vector3.forward, transform.InverseTransformPoint(position))>0){
		// Move the character
		GetComponent (CharacterController).SimpleMove(transform.forward * walkSpeed);
		animation.CrossFade("WalkForward", 0.3);
		Debug.DrawLine(transform.position, position, Color.yellow);
	} else {
		Debug.DrawLine(transform.position, position, Color.red);
	}
	
	return false;
}

function MoveToTarget (target : Transform){ 
	MoveTowards(target.position);
}

function Patrol(){
	if(! MoveTowards(patrolPoints[curWayPoint])){
		curWayPoint+=patrolDirection;
		if(patrolLoops){
			if(curWayPoint == patrolPoints.Length){
				curWayPoint=0;
			}
		}else{
			if(curWayPoint == patrolPoints.Length || curWayPoint == -1){
				patrolDirection = patrolDirection == 1 ? -1 : 1;
				curWayPoint += patrolDirection * 2;
			}
		}
		// do the updated move:
		MoveTowards(patrolPoints[curWayPoint]);
	}
}

Thanks for replying, I will check your changes in a bit.

It looks slightly more complex than how I was approaching it. FYI I wasn’t using both MoveTowards and MoveToTarget functions, it was either one or the other with MoveTowards being passed the Vector3 and MoveToTarget being passed the next waypoint gameObject.

The later worked just fine, but the Vector method did not.

Thanks for you code, I look forward to giving it a play.

I’ve figured out, but not solved the problem. I looked at your code, but couldn’t implement it successfully, but it helped to have a fresh approach, so thanks.

It seems that it is the use of the GetComponent (CharacterController).SimpleMove(transform.forward * walkSpeed); function that is causing the waypoint to not update, removing this it they work fine, however I really need collision here and don’t quite understand why this would be the case.