- Home /
Why is this coroutine only firing once?
I'm trying to make a script to make an enemy jump up and descend when the player approaches. The problem is that the coroutine controlling the enemy movement is only firing once. I did also try putting putting the contents of the coroutine into a while loop, but everything I tried with while either ended up with the same results or crashing Unity.
using UnityEngine;
using System.Collections;
public class Enemy_2 : MonoBehaviour {
public float distance;
public float lerp_value;
public bool attack_triggered;
public Vector3 bottom;
public Vector3 top;
public GameObject player;
public GameObject enemy;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
distance = Vector2.Distance (player.transform.position, enemy.transform.position);
if (distance < 15 && attack_triggered == false) {
attack_triggered = true;
StartCoroutine ("Jumping");
}
}
IEnumerator Jumping () {
if (transform.position != top) {
lerp_value += 0.1f;
Debug.Log ("Fire");
transform.position = Vector3.Lerp (bottom, top, lerp_value);
}
else if (transform.position == top) {
StartCoroutine ("Falling");
StopCoroutine ("Jumping");
}
yield return null;
}
IEnumerator Falling () {
if (transform.position != bottom) {
lerp_value -= 0.1f;
transform.position = Vector3.Lerp (top, bottom, lerp_value);
}
else if (transform.position == bottom) {
attack_triggered = false;
StopCoroutine ("Falling");
}
yield return null;
}
}
Answer by Bunny83 · Aug 04, 2014 at 12:04 AM
Well, since you don't have a while loop in your coroutine, it will of course only run once when you start it once. This condition:
if (transform.position == top)
is suboptimal since you compare floating point values and the position property might go through some transformations (local to world and world to local). It's better to check the lerp value.
Next thing is you increase your lerp value from 0 to 1 and lerp from bottom to top. However in falling you start at 1 and lerp back to 0 but you have reversed top and bottom. So you again lerp from bottom to top.
Is it important to use two coroutines? It would be easier that way:
IEnumerator Jumping ()
{
// start jumping
for (float t = 0; t < 1; t += Time.deltaTime)
{
transform.position = Vector3.Lerp (bottom, top, t);
yield return null;
}
// start falling
for (float t = 0; t < 1; t += Time.deltaTime)
{
transform.position = Vector3.Lerp (top, bottom, t);
yield return null;
}
// done
attack_triggered = false;
}
ps: At the moment i increase t by Time.deltaTime which will make the jump-up take 1 second and the falling will also take 1 second. You can divide it by you desired time it should take.
float jumpTime = 2.0f; // two seconds
for (float t = 0; t < 1; t += Time.deltaTime / jumpTime )
Answer by robertbu · Aug 03, 2014 at 11:55 PM
Coroutines only continue their processing if you put in a loop of some sort. And they are like any other function...once you hit the bottom, the coroutine is done. A usual structure:
while('some condition') {
// Some code here that does something repeatedly over time
yield return null;
}
In the particular case of your Jumping method, you could do:
IEnumerator Jumping () {
while (transform.position != top) {
lerp_value += 0.1f;
transform.position = Vector3.Lerp (bottom, top, lerp_value);
yield return null;
}
StartCoroutine ("Falling");
}
Note you should really be using deltaTime when modifying your lerp_value.
Answer by Ghosthowl · May 17 at 07:51 AM
Since this is the top result for this issue, I had this issue as well with Unity 2021 and the answer was completely different than any of the other suggestions.
It turns out I was using
SceneManager.MoveGameObjectToScene(gameObject, scene);
After my StartCoroutine. Internally Unity must do something during this move that cancels all coroutines, so my coroutine was only running once. After moving my StartCoroutine to after the Move, my coroutine ran as normal.
Your answer
Follow this Question
Related Questions
Static Coroutine being called endlessly 2 Answers
Crash on loop using Lerp. 1 Answer
Executing coroutines consecutively 0 Answers
bounce player back to position while jumping 0 Answers
Lerp not working inside Coroutine. 1 Answer