Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
1
Question by mlkielb 1 · Sep 23, 2010 at 02:23 PM · coroutineienumeratorcancel

Cancel IEnumerator in progress

I have a script that I'm trying to use to track when a player goes out of the map's bounds. If the player doesn't get back in bounds in ten seconds his unit is destroyed. The script works when the player goes out of bounds, but the IEnumerator doesn't stop when he returns to the map.

The bounds is just a box trigger, when the player exits it starts the coroutine, and when he enters I need it to stop the coroutine. Thank you.

void OnTriggerEnter (Collider other) {

 GameObject go = other.gameObject;

 if(go.transform.root.gameObject.CompareTag("Player")){
     status = go.transform.root.gameObject.GetComponent<NetPlayer>();
     status.outOfBounds = false;
 }

}

void OnTriggerExit (Collider other) {

 GameObject go = other.gameObject;

 if(go.transform.root.gameObject.CompareTag("Player")){
     status = go.transform.root.gameObject.GetComponent<NetPlayer>();
     status.outOfBounds = true;
     StartCoroutine(OutOfBounds(10));
 }

}

IEnumerator OutOfBounds(float secs){ float cd = secs; while(status.outOfBounds == true){ while(cd > 0){ yield return new WaitForSeconds (1); GameObject.Find("MessageText").gameObject.GetComponent<GUIText>().text = "You are leaving the battle.\nReturn to battle or be destroyed.\n" + cd ; cd --; } GameObject.Find("MessageText").gameObject.GetComponent<GUIText>().text = ""; yield return new WaitForSeconds (.2F); status.hullHealth = 0; } }

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
2
Best Answer

Answer by skovacs1 · Sep 23, 2010 at 02:50 PM

It's not an IEnumerator. The IEnumerator is the return type of the co-routine. You want to stop the coroutine.

You have the co-routine that does the following:

IEnumerator OutOfBounds(float secs){
    float cd = secs; 
    //Loop conditionals are checked at the end of each iteration.
    //Is there a point in having this?
    //Are you going to kill them multiple times when you don't set outOfBounds = false?
    while(status.outOfBounds == true){
        //Wait secs seconds, posting the message every second
        while(cd > 0){
            yield return new WaitForSeconds (1);
            GameObject.Find("MessageText").gameObject.GetComponent<GUIText>().text =
                "You are leaving the battle.\nReturn to battle or be destroyed.\n" + cd ;
            cd --;
        }
        GameObject.Find("MessageText").gameObject.GetComponent<GUIText>().text = "";
        //Wait .2 seconds and then kill them
        yield return new WaitForSeconds (.2F);
        status.hullHealth = 0;
    }
}

Your co-routine has nothing to stop it until it kills the character and a loop that can do it multiple times. Try to understand what your code is doing as this lack of understanding is the cause of most difficulties.

To do what you're describing, try doing something like:

IEnumerator OutOfBounds(float secs){
    float cd = secs; 
    while(cd > 0) { //Check over secs seconds
        if(!status.outOfBounds) break; //If we're back in bounds, we're done
        yield return new WaitForSeconds (1);
        GameObject.Find("MessageText").gameObject.GetComponent<GUIText>().text =
       "You are leaving the battle.\nReturn to battle or be destroyed.\n" + cd ;
        cd --;
    }
    GameObject.Find("MessageText").gameObject.GetComponent<GUIText>().text = "";
    if(status.outOfBounds) { //We're still out of bounds after secs seconds
        yield return new WaitForSeconds (.2F);
        status.hullHealth = 0;
    }
}
Comment
Add comment · Show 2 · 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 mlkielb 1 · Sep 23, 2010 at 03:19 PM 0
Share

Thank you. All I needed was the break statement. The way the rest of my project is structured it will only kill him once, not multiple times.

avatar image skovacs1 · Sep 24, 2010 at 02:50 PM 0
Share

Then why do you have that while loop while(status.outOfBounds == true) if you're only doing one iteration of the loop?

avatar image
6

Answer by Eric5h5 · Sep 23, 2010 at 03:14 PM

You can use StopCoroutine to cancel an existing coroutine, but it must be started using the string version.

Comment
Add comment · Show 2 · 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 Gellist · Dec 08, 2018 at 10:02 AM 0
Share

This totally is what I needed! Was using a trigger with a delay to change scenes if you stayed in for 5 seconds, but when he exited the trigger it wouldn't cancel the task, it would still change scenes.

I had written it :

         StartCoroutine (delayTask());

 and not

     StartCoroutine ("delayTask");
 

 
avatar image Bunny83 Gellist · Dec 08, 2018 at 01:59 PM 1
Share

This is actually outdated. In the past you could only stop coroutines which were started using a string. In the recent Unity versions they added overloads for StopCoroutine which takes either the IEnumerator instance that was used to start the coroutine, or the Coroutine object that is returned by StartCoroutine. In most cases the simplest solution is to store the Coroutine object in a variable

 Coroutine co;
 
 // [ ... ]
 
 co = StartCoroutine(delayTask());
 
 // [ ... ]
 
 StopCoroutine(co);

This is much better for refactoring (since the name of the method isn't inside a string) and is also faster.

avatar image
1

Answer by Dreamora · Sep 23, 2010 at 04:48 PM

Or you use StopAllCoroutines() to kill all on that GO

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

2 People are following this question.

avatar image avatar image

Related Questions

Coroutine won't run sometimes and other times it runs. 0 Answers

Can't get past WaitForSeconds in my coroutine 1 Answer

Coroutine doesn't work when called from another method. 3 Answers

c# Using an IEnumerator yield WaitForSeconds to temporarily pause a While loop 3 Answers

WaitForSeconds is breaking out of my IEnumerator 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