Search Unity

How can I stop, start and reset a coroutine?

Discussion in 'General Discussion' started by rosannacap29, Dec 1, 2020.

  1. rosannacap29

    rosannacap29

    Joined:
    Sep 30, 2020
    Posts:
    4
    Hello, I have 645 objects that are animated using the following script:

    Code (CSharp):
    1.  using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class ArrayTest : MonoBehaviour
    5. {
    6.      public GameObject[] numbers;
    7.      // Start is called before the first frame update
    8.      void Start()
    9.      {
    10.        
    11.      }
    12.      bool attractorMode = true, isRunning;
    13.      int currentIndex;
    14.      // Update is called once per frame
    15.      void Update()
    16.      {
    17.          // only invoke if the coroutine isn't already running
    18.          if (attractorMode && !isRunning) StartCoroutine(Cycle());
    19.      }
    20.      IEnumerator Cycle()
    21.      {
    22.          // these lines execute by the end of the frame in which Cycle() was invoked
    23.          isRunning = true;
    24.          numbers[currentIndex].SetActive(true);
    25.          yield return new WaitForSeconds(0.25f);
    26.      
    27.          // execution will not return to the next statement until 0.25 seconds later  
    28.          numbers[currentIndex].SetActive(true);
    29.          Destroy(numbers[currentIndex], 0.05f);
    30.      
    31.          // increment the index and ensure it loops around at the end
    32.          currentIndex++;
    33.          if (currentIndex >= numbers.Length) currentIndex = 0;
    34.          isRunning = false;    
    35.        
    36.        
    37.      }
    38. }
    39.  
    Now the problem is that I have created some buttons: play, stop and reset.

    How do I link these buttons to my animation script?

    Sorry, but I'm a beginner with Unity.

    Thanks to anyone who wants to help me.
     
  2. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    I recommend placing scripting questions in the scripting forum.

    I also recommend going to Unity Learn and searching the things you're interested in, and doing the tutorials, before asking a question here. It may be addressed there (hint: it is), along with other helpful information.
     
  3. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,982
    You can hook up the methods in the c# script to the buttons via the button component in the inspector. Best to follow some basic tutorials though, as you would have gone through this if you did.

    https://learn.unity.com/course/create-with-code

    Its recommended to start with (and complete) that set of tutorials if you want to get anywhere without frustrations down the line :)
     
    Amon likes this.
  4. DanielCoulson

    DanielCoulson

    Joined:
    Dec 6, 2020
    Posts:
    1
    As others have said, your best bet is to learn basics on Unity Learn. The better you understand the basics, the less time you spend on simple tasks like this.
     
    Last edited: Dec 8, 2020
  5. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,853
    You may want to consider a timer that increments using Time.deltaTime. That is one helluva lot of garbage collection from 645 coroutines.
     
    Ryiah likes this.
  6. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,571
    You kinda don't pause a coroutine. It is not a Thread.
    It is always being executed from the last point to the next yield return (or end of the function).

    So, as long as it is active, it will be called every frame frame and execute till the next yield return (or till the end).

    You can set up an external condition and immediately yield return when the coroutine is "paused", but it still will eat a couple of cpu cycles as it will be essentually busy waiting. yield return new WaitForSeconds(...), most likely works the same way.

    Also see: https://docs.unity3d.com/ScriptReference/Coroutine.html
     
    MadeFromPolygons and Ryiah like this.
  7. Meltdown

    Meltdown

    Joined:
    Oct 13, 2010
    Posts:
    5,822
    All of these questions could have been answered by literally typing into google, Start Coroutine, Pause Coroutine, and Stop Coroutine.

    If you're new to coding and Unity you're going to be doing a LOT of Googling for answers of stuff, asking questions on the forum for something that is well documented or that other people have asked many times, is not the most efficient way for you to learn.
     
    MadeFromPolygons likes this.
  8. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Coroutines are just code, you can do prettty much anything with them. But they are not pauable,.You can stop them and start them again.

    You can even jump between states. Like in our game

    Code (CSharp):
    1.         public override IEnumerator Execute()
    2.         {
    3.             var firearm = Get<Firearm>();
    4.  
    5.             topItem = GetAll().Select(r => r.GetComponent<SimpleNetworkedMonoBehavior>()).First(r => r.Prefab.name == Prefab.name).GetComponent<NVRInteractable>();
    6.             railSystem = firearm.GetComponent<RailSystemContainer>().RailSystems[RailIndex];
    7.             attachment = topItem.GetComponent<RailSystemAttachment>();
    8.  
    9.             yield return Execute(WaitForAttachmentGrab, WaitForAttachmentHoveringOverRail, WaitForPlacementOnRail);
    10.         }
    Code (CSharp):
    1.         private IEnumerator WaitForPlacementOnRail()
    2.         {
    3.             ShowPopup(railSystem.transform, "Slide the attachment over the rail until you find a good position and let go.");
    4.  
    5.             while (!attachment.IsCompletelyAttached)
    6.             {
    7.                 if (attachment.AttachedSystem != railSystem)
    8.                     yield return SequenceState.Previous;
    9.                 else
    10.                     yield return null;
    11.             }
    12.         }
    It will always be a small overhead though per coroutine. Since you iterate all your 600 objects from one coroutine thats not a problem
     
    Last edited: Dec 7, 2020