My script makes unity freeze when pressing play.

Playing around coroutines, but got stuck on this one, pretty sure it’s the while loop, but I don’t get it why? :smile:

The point of this script, is just to move an object smoothly using Vector3.Lerp to random locations. :wink:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CoroutinePrototype : MonoBehaviour {

    // Use this for initialization
    void Start () {
        Vector3[] coordinateArray = new Vector3[16]; //create an Array
        for (int i = 1; i < 16; i++) {
            coordinateArray [i] = new Vector3 (RandomCoordinate (), RandomCoordinate (), RandomCoordinate ()); //put vector in each slot of array with random values
        }

        StartCoroutine(SendCords(coordinateArray, 1f)); //start cooroutine
    }
  
    float RandomCoordinate(){ //random value generator
        float randomNumber = Random.Range (-50f, 50f);
        return randomNumber;

    }

    void moveTo(Vector3 location) { //function to move object to specified location (parameter)
        Debug.Log ("Moving object to location:" + location);
        transform.position = Vector3.Lerp(transform.position, (transform.position - location), 0.01f);
        Debug.Log ("Arrived");  
    }

    IEnumerator SendCords (Vector3[] coordinates, float delay){ //the premise of this coroutine is to have a "efficient" delay between each move to location
        foreach (Vector3 location in coordinates) { //go through the array and pass values to variable location
            while (Vector3.Distance(transform.position, location) > 0.05f) { //while the distance between object and location is bigger, run function moveTo
                moveTo (location); //move the object
            }
            yield return new WaitForSeconds (delay); //delay between each move (object moves slowly using lerp, successfully gets to the point, then delay happens and it repeats)
        }
    }

    // Update is called once per frame
    void Update () {
      
    }
}

Try including a yield return inside your while loop. I bet your problem is there.

I did that, but the object moves to one random location slowly, moving a tiny bit each iteration of coroutine (delay of 1sec), mhm can’t spot the issue… Can you? :eyes:

You don’t have to wait a second in your coroutine, you can wait a frame

Rotary-Heart is right.

This right here:

while (Vector3.Distance(transform.position, location) > 0.05f) { //while the distance between object and location is bigger, run function moveTo
    moveTo (location); //move the object
}

Which is effectively doing this:

void moveTo(Vector3 location) { 
    transform.position = Vector3.Lerp(transform.position, (transform.position - location), 0.01f); 
}

Well… it’s lerp amount is 0.01, this is a very small amount. And because as you get closer and closer you keep doing a 1% move toward, you’re effectively moving slower and slower towards the target.

Also, your target position is weird. You’re not going from position to location, you’re going from position to a point equal to the vector position - location. You probably mean to do:

void moveTo(Vector3 location) { 
    transform.position = Vector3.Lerp(transform.position, location, 0.01f); 
}

AND, you’re attempting to do this all in one frame.

Now you say:

Well, the location is not random… it’s along the line starting from position towards, well towards your bad location.

And of course it’s moving tiny bits, it’s a lerp value of 0.01

And you’re waiting 1 second between updates… maybe wait a single frame?

while (Vector3.Distance(transform.position, location) > 0.05f) { //while the distance between object and location is bigger, run function moveTo
    moveTo (location); //move the object
    yield return null; //waits 1 frame
}

And also that 0.01, it’s a weird arbitrary value.

Also, because it’s lerp, you’re going to get a non-linear velocity. It’ll slow down as you approach the goal.

You might want Vector3.MoveTowards:

void moveTo(Vector3 location, float speed) { 
    transform.position = Vector3.MoveTowards(transform.position, location, speed * Time.deltaTime); 
}

Put that all together, and you’ll probably get what you’re looking for.

1 Like

Yup, that made it work as I wanted it to, I should have looked how to use Lerp… Very clear and thorough explanation though, really appreciated…:smile: