Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by Hideyoshi_K · Aug 03, 2014 at 11:47 PM · transformcoroutinelerploopienumerator

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;
     }
 }
 
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
4
Best Answer

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 ) 
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robertbu · Aug 04, 2014 at 12:42 AM 0
Share

Better answer +1

avatar image
1

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.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

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.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Static Coroutine being called endlessly 2 Answers

bounce player back to position while jumping 0 Answers

Lerp not working inside Coroutine. 1 Answer

Problems with do-while loops and IEnumerator 1 Answer

Crash on loop using Lerp. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges