Problems with waypoint script

Hello folks,

I’ve just finished a few books and tutorials on unity scripting, so I decided to try some things out. I wrote this waypoint script to test some things however I’m having some problems with it.

using UnityEngine;
using System.Collections;

public class move : MonoBehaviour {
	
	
	public GameObject[] waypoint;
	private int i=0;
	// Use this for initialization
	void Start () {
		
	
	}
	
	// Update is called once per frame
	void Update () {
		
			
		this.transform.position=Vector3.Lerp(transform.position,waypoint[i].transform.position,Time.time);
		if(this.transform.position==waypoint[i].transform.position)
		{
			if(i==2)
				i=0;
			else
				i++;
			
		}
		
		
	  			
	}
	
	
}

Right now the script goes to all 3 points and loops, which is what I want, however the object just keeps moving between the points faster and faster until it looks like it’s at all the points at the same time. I changed the Time.time to deltaTime in the script, but when I do that, the object just goes to the 1st point and stops. Any ideas?

switch Time.time with time.deltaTime*speed

speed=5.0 or something

try that?

That did it, not sure why it would move once though with no speed variable, weird, thank you sir!

Time.Time is the total run time of the game… so naturally it starts at 0 and gets larger, hence moving more and more.

Hmm its working, but not exactly the way I want, there is a bit of a delay once the object reaches a way point, and if the speed is set to lower then 5 it seems to just sit at the 1st way point and not go any further, anyone have any ideas?

using UnityEngine;
using System.Collections;

public class move : MonoBehaviour {
	
	
	public GameObject[] waypoint;
	public Transform[] waypointT;
	public float speed;
	private int i=0;
	private int	numOfWaypoints;
	private float amtToMove;
	
	// Use this for initialization
	void Start () {
	
		numOfWaypoints=waypoint.Length-1;
		amtToMove=speed * Time.deltaTime;
	}
	
	// Update is called once per frame
	void Update () {
		
		this.transform.position=Vector3.Lerp(transform.position,waypoint[i].transform.position,amtToMove);
		transform.LookAt(waypointT[i]);
		if(transform.position==waypoint[i].transform.position)
		{
			if(i==numOfWaypoints)
				i=0;
			else
				i++;
		}
	}
	
}

thats cause you’ve used lerp

I would use transform.Translate or Vector3.MoveTowards if you want to use a constant speed

This is what I use for my waypoints!

var waypoint : Transform[];

var speed : float = 20;

private var currentWaypoint : int;

var loop : boolean = true;









function Update () {

	if(currentWaypoint < waypoint.length){

		var target : Vector3 = waypoint[currentWaypoint].position;

		var moveDirection : Vector3 = target - transform.position;

	

		var velocity = rigidbody.velocity;

	

		if(moveDirection.magnitude < 1){

			currentWaypoint++;

		} else {

			velocity = moveDirection.normalized * speed;

		}

	} else {

		if(loop){

			currentWaypoint = 0;

		} else {

			velocity = Vector3.zero;

		}

	}

	

	rigidbody.velocity = velocity;

Thanks, Vector3.MoveTowards worked, transform.Translate I’m still trying how to figure out how to move it in the direction of the object.

Well as long as the object is facing the target…

transform.Translate(Vector3.forward * speed * Time.deltaTime);

Interesting, the only problem I’m having with your code is this line

var velocity = rigidbody.velocity;

what kind of variable type is velocity?

edit: nevermind figured it out it’s a Vector3, I’ve converted your code to C# just in case anyone is interested, it works quite well.

using UnityEngine;
using System.Collections;

public class moveT : MonoBehaviour {

	public Transform[] waypoint;
	public float speed;
	private int currentWaypoint;
	private bool loop=true;
	private Vector3 velocity;
	
	void Start()
	{
		
	}
	
	void Update()
	{
		if(currentWaypoint < waypoint.Length)
		{
			Vector3 target = waypoint[currentWaypoint].position;	
			Vector3 moveDirection = target-transform.position;
			
			velocity = rigidbody.velocity;
			
			if(moveDirection.magnitude<1)
			{
				currentWaypoint++;
			}
			else
			{
				velocity=moveDirection.normalized*speed;
			}
		}
		else
		{
			if(loop)
			{
				currentWaypoint=0;
			}
			else
			{
				velocity=Vector3.zero;
			}
		}
		rigidbody.velocity=velocity;
	}
}

Cool, I’ll give that a try as well to see if it looks better.

The only problem I find with that code is that the turning is a bit too blunt. Needs to have some smoothing on it really. Also, not sure why but I copied the wrong one. It looks like this really:

var waypoint : Transform[];

var speed : float = 20;

private var currentWaypoint : int;

var loop : boolean = true;



function Update () {

	if(currentWaypoint < waypoint.length){

		var target : Vector3 = waypoint[currentWaypoint].position;

		var moveDirection : Vector3 = target - transform.position;

		transform.LookAt(target);

	

		var velocity = rigidbody.velocity;

	

		if(moveDirection.magnitude < 1){

			currentWaypoint++;

		} else {

			velocity = moveDirection.normalized * speed;

		}

	} else {

		if(loop){

			currentWaypoint = 0;

		} else {

			velocity = Vector3.zero;

		}

	}

	

	rigidbody.velocity = velocity;

	animation.Play();

		

}



function OnDrawGizmos(){

       

        Gizmos.color = Color.red;

        for(var i : int = 0; i< waypoint.Length;i++)

        {

           var pos : Vector3 = waypoint[i].position;

            if(i>0)

            {

                var prev : Vector3 = waypoint[i-1].position;

                Gizmos.DrawLine(prev,pos);

            }

        }

    }

You can of course apply similar functions within the rotation rather than using lookAt if its too snappy.

There are RotateTowards/Slerp functions for the Quarternions. Then you just have to decide how you want the movement to work… ie, do you want to wait until the object is facing towards the target before you move towards, or do you want to have the object move as he rotates.

How would I set that up? Ideally for what I’m working on I’d need the object to rotate as its moving!

If I try and put in any kind of commands to make it look towards the next target all it does is always look at the first

Something like this should work… not sure if this will compile since im writing it from memory

Transform target;
float WalkSpeed = 5;

void Update()
{

if(target != null)
{
      Vector3 relativePos = target.position - transform.position;
      Quaternion rotation = Quaternion.LookRotation(relativePos);

      transform.rotation = Quarternion.RotateTowards(transform.rotation, rotation, 5);
      transfrom.Translate(Vector3.forward * WalkSpeed * Time.deltaTime);

}

}

Just out of curiosity, how does unity determine what the front of an object is?

Transform.forward

Transform.forward == Transform.Tranlsate(Vector3.forward)

Its a normal. Normals always have a length of 1. So Transform.position += transform.forward * speed * Time.deltaTime is the same thing as what you have.