yield works only once

I have a simple JS script

    function Update () 
                {
		var x : float;
		var y : float;
		x = Random.Range(-15,15);
		y = Random.Range(-15,15);
   		goFar(x,y);
                }

        
function goFar (a,b)	
        {
	timer = 0.0;
	newPosition = transform.position;
	while(timer < 1.0)
	    {
		transform.position = Vector3.Lerp(newPosition, Vector3(a,0,b), timer);
		timer = timer + 0.01;
		yield;
	    }
        }

It’s supposed to create random coordinates and smoothly move the game object there. But it goes smoothly only once, and after that the game object just jumps from place to place because the whole timer increment is done within one frame. It looks like “yield” works only the first time the “goFar” function is called. What am i missing here?

Your code starts a new coroutine every frame. I’m not sure if timer is a member variable of your class, but from your description of your problem that’s most likely. So every coroutine works on the same timer variable. That means every frame it would be set to 0 and each running coroutine will do one while iteration. The more coroutines are running the more increments you will have each frame.

100 coroutines never exit since each Update you create a new one which sets the timer to 0. Right after the coroutines will do the next while iteration. Since there are 100 coroutines running within the same frame you instantly increment up to 1. The last coroutines will actually terminate themself since timer is now 1.

The next frame the same happens again. If you want to only pick a new target position when you reached the old one, you either doing everything in one coroutine, or you use a boolean variable to prevent the creation of a new coroutine while there is already one running.

Also since the framerate can vary heavily you should use Time.deltaTime to increment your timer. Time.deltaTime added each frame will add up to 1.0 within one second. That way your timer get actually time-based and is not frame-based.

function Start ()
{
    GoRandom();
}
 
 
function GoRandom()
{
    while( true )
    {
        var x = Random.Range(-15,15);
        var z = Random.Range(-15,15);
        var target = Vector3(x, 0, z);
        var timer = 0.0;
        var oldPosition = transform.position;
        while(timer < 1.0)
        {
            transform.position = Vector3.Lerp(oldPosition, target, timer);
            timer = timer + Time.deltaTime;
            yield;
        }
    }
}

I renamed some variables and made them all local variables since it doesn’t make much sense to have them member variables. The coroutine “GoRandom” is started once in start and will run infinitely.