Coroutine not starting from Update

hello, I wrote a script around me that will return to it when a character appears in a random place, but the problem was that if I run this function on the button, it works, but if I write it in the update method, the code does not work at all, even the working button starts to stop working, but if I remove it from the update method again, the button is the same. it runs the function, but somehow I couldn’t run it in the update method code:

public void startRotating ()
{
    if (LookCoroutine != null)
    {
        StopCoroutine(LookCoroutine);
    }
    LookCoroutine = StartCoroutine(LookAt());
}

public IEnumerator LookAt ()
{
    Quaternion lookRotation = Quaternion.LookRotation(target.position - transform.position);
    float time = 0;
    while (time < 1)
    {
        transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, time);
        time += Time.deltaTime * speed;
        yield return null;
    }
}

void OnGUI ()
{
    if (GUI.Button(new Rect(10, 10, 200, 30), "LookAt"))
    {
        starting();
    }
}

this example works for me but if i do something like

void Update ()
{
    starting();
}

this but it doesn’t work for me in any way what is the reason for this how can i fix it i would appreciate if you help me.

Hi, @Tunahanakargul,

Try to check is your Coorutine not running multiple time…

Maybe add:

bool m_coorutineIsRunning = false;

void Update()
{
If (!m_coorutineIsRuning) StartCorutine(LookAt());
}

public IEnumerator LookAt()
 {
         m_coorutineIsRunning = true;
         // your code
         yield return null;
         m_coorutineIsRunning = false;
 }

Uhm, your “startRotating” method does first stops the current running coroutine before starting a new one each frame. So none of your coroutines will ever really run. They all just run up to their first yield and the next frame, when you call “startRotating” again, you stop the coroutine and start a new one. This does not make much sense from the logical point of view.

Starting and stopping coroutines is kinda expensive and if possible you should avoid that. It’s far better to keep a single coroutine running. Though from your code it’s hard to tell what this is actually supposed to do or how you want to use it. Calling startRotating in Update just makes no sense at all. Besides that using Slerp this way also doesn’t make that much sense. Assuming that the coroutine would actually run through, your current use of slerp would result an an accelerated rotation that gets faster and faster towards the end. So using Slerp this way would not be consistent and also changes with the frame rate. Using RotateTowards usually makes more sense. It rotates with a constant rotational speed towards a target rotation when called every frame.

If you just want this object to look at the target (if a target is given), why don’t you just do something like this:

void Update()
{
    if (target != null)
    {
        var targetRot = Quaternion.LookRotation(target.position - transform.position);
        transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRot, speed * Time.deltaTime);
    }
}

There’s no need for a coroutine here if you want this behaviour.