How do I stop coroutine based on the condition

I am using Coroutine to make the player move based on the list of the sequence in the game. And i want to StopCoroutine() when the player collide with the collider. But when i run the code, it cannot detect the game object with collider so the player will not stop moving eventhough its collide with the collider. Can unity members help me solve this problem? T^T

public class Controller : MonoBehaviour
{
public void OnPlayButtonClicked()
{
    Play();
}

public void Play()
{
    sequence_.Clear();
    sequence_ = new List<Function_>();
    TranslateCodeFromBlocks(canvas_.transform, sequence_);
    if (sequence_.Any(item => item.ID == "Function_Function"))
    {
        Transform childTransform = secondCanvas.transform.GetChild(0);
        TranslateCodeFromBlocksFunction(childTransform, insideFunction);
        loop2 = new MainLoop(mainTarget, insideFunction, animator);
        //StartCoroutine(loop2.Play());

    }
    //Debug.Log(sequence_);
    loop1=new MainLoop(mainTarget, sequence_, animator);
   
        StartCoroutine(loop1.Play());

}
}
public class MainLoop : MonoBehaviour
{
    public IEnumerator Play()
    {
        foreach (Function_ fun in sequence_)
        {
            fun.Func(animator, rb);
            Collider2D[] childColliders = GameObject.Find("Track").GetComponentsInChildren<Collider2D>();
            Transform parent=GameObject.Find("Track").GetComponent<Transform>();

            foreach (Transform child in parent)
            {
                if (child.GetComponent<Collider2D>() != null)
                {
                    if (mainTarget.IsTouching(child.GetComponent<Collider2D>()))
                    {
                        Debug.Log(child.gameObject);   
                        continue; // Exit the loop since a collision has been detected
                    }
                    
                }
                else
                {
                    Debug.Log("Child object doesn't have a collider");
                }

            }
            WaitForSeconds wait = new WaitForSeconds(waitTime);
            this.end = false;    
            yield return new WaitForSeconds(1);
        }
    }
}

You can stop in 2 ways :

  • You can stop from within the coroutine by doing a yield break
  • You can stop from anywhere using StopCoroutine by actually saving the handle to the coroutine first , StartCoroutine actually returns a Coroutine “handle object” that you can save like thisCoroutine myCrt = StartCoroutine(Play());
    Then you can call StopCoroutine(myCrt) and pass the handle as a parameter

You can try adding a
IEnumerator currentLoop; to assign your coroutine. Rather than calling
StartCoroutine(loop1.play());
You will assing the loop1.play() in currentLoop = loop1.Play().
when you call StopCoroutine() just pass in the currentLoop as variable. Also make sure to check for null.
Let me know if it helps you.

Rewrote here for ease:

In your controller class, you are starting the coroutine with StartCoroutine(loop1.Play()); instead of doing that all you have to do is storing the coroutine before you start it so that you can disable it from anywhere. To store the coroutine:

public IEnumerator currentLoop; 

//in controller play function: 
loop1=new MainLoop(mainTarget, sequence_, animator); 
currentLoop = loop1.Play(); StartCoroutine(currentLoop);

Having a public ienumerator means that you can stop the coroutine from everywhere that can access to the controller class.
But if you want to do this inside the MainLoop you can just use yield break; as @bloodthirst69 suggested as it would be easier to follow. I usually store the coroutine that ı want to star/stop so i didnt think of the yield break;