Problems with using Courintine

Hello Community,
This is a tricky problem and I cant seem to figure out a solution to this. I would really appreciate the help, I assure you i have searched and tried multiple things to solve it with no luck so far.

Basically My game has gameobjects that are moving throughout assigned positions, like, gameobjects spawned every 2 sec, moves through position 1 all the way to position 6 with 2 sec delay on each position.

Now i am dragging and dropping a new gameobject on top of the moving gameobjects which will destroy both gameobjects and make the bottom gameobjects move upward to fill out the gap and continue the chain.

This works fine with I take time and drop one gameobject at a time, but if I try to drop gameobjects fast the chain breaks, this is the part I cant figure out at all. I need to know where the problem is, if its the usage of courintine or some stupid mistake that I am overlooking. Here is the code:

UPDATE: updated my code please take a look at it

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ScriptMoveUserBox : MonoBehaviour {

    bool beltStart;
     GameObject[] positions;
    GameObject pos1,pos2,pos3,pos4,pos5,pos6,pos7,pos8;
    public GameObject cube, textGOPrefab, imageGOPrefab , botCube, parentGameObject;
     int stepNo;
    float timeDelay=2;
    public float timeDelayM =2;
    static public float speed=100,step=0;
    bool processStarted;
    Coroutine m_MyCoroutineReference;

    public GameObject animGameObject;


    float timerDelay,timerDelayTop,timerDelayBot;
    bool resetTime;
    int topGameObject, botGameObject;

    Coroutine c1 ;
    Coroutine c2 ;

    public Image PrefabImage;

    // Use this for initialization
    void Start () {

            pos1 = GameObject.FindGameObjectWithTag("position1");
            pos2 = GameObject.FindGameObjectWithTag("position2");
            pos3 = GameObject.FindGameObjectWithTag("position3");
            pos4 = GameObject.FindGameObjectWithTag("position4");
            pos5 = GameObject.FindGameObjectWithTag("position5");
            pos6 = GameObject.FindGameObjectWithTag("position6");
            pos7 = GameObject.FindGameObjectWithTag("position7");
            pos8 = GameObject.FindGameObjectWithTag("position8");
    }


    // Update is called once per frame
    void Update () {


        if(topGameObject==0 &&     ScriptManager.stopMachine ==false){

            ContinueCycle();


        }

    }

    public void ContinueCycle(){

 
        if(stepNo == 0){
            timeDelay=timeDelayM;
            m_MyCoroutineReference = StartCoroutine(Step1());

        }else  if(stepNo == 1){
            timeDelay=timeDelayM;
            m_MyCoroutineReference = StartCoroutine(Step2());

        }else  if(stepNo == 2){
            timeDelay=timeDelayM;
            m_MyCoroutineReference = StartCoroutine(Step3());

        }else  if(stepNo == 3){
            timeDelay=timeDelayM;
            m_MyCoroutineReference = StartCoroutine(Step4());

        }else  if(stepNo == 4){
            timeDelay=timeDelayM;
            m_MyCoroutineReference = StartCoroutine(Step5());


        }else  if(stepNo == 5){
            timeDelay=timeDelayM;
            m_MyCoroutineReference = StartCoroutine(Step6());

        }
        else  if(stepNo == 6){
            timeDelay=timeDelayM;
            m_MyCoroutineReference = StartCoroutine(Step7());

        }
        else  if(stepNo == 7){
            timeDelay=timeDelayM;
            m_MyCoroutineReference = StartCoroutine(Step8());

        }



    }

    IEnumerator Step1() {
        step = speed * Time.deltaTime;

        this.transform.position = pos1.transform.position;
        yield return new WaitForSeconds(timeDelay);
        if(beltStart == false || ScriptManager.stopMachine==false){
        stepNo=1;
        }
        else{
            yield return null; //Done
        }



    }

    IEnumerator Step2() {

        this.transform.position = pos2.transform.position;

        yield return new WaitForSeconds(timeDelay);
        if(beltStart == false || ScriptManager.stopMachine==false){
            stepNo=2;
        }
        else{
            yield return null; //Done
        }

    }

    IEnumerator Step3() {
        this.transform.position = pos3.transform.position;

        yield return new WaitForSeconds(timeDelay);
        if(beltStart == false || ScriptManager.stopMachine==false){
            stepNo=3;
        }
        else{
            yield return null; //Done
        }
    }

    IEnumerator Step4() {

        this.transform.position = pos4.transform.position;

        yield return new WaitForSeconds(timeDelay);
        if(beltStart == false || ScriptManager.stopMachine==false){
            stepNo=4;
        }
        else{
            yield return null; //Done
        }
    }

    IEnumerator Step5() {

    this.transform.position = pos5.transform.position;

        yield return new WaitForSeconds(timeDelay);
        if(beltStart == false || ScriptManager.stopMachine==false){
            stepNo=5;
        }
        else{
            yield return null; //Done
        }
    }

    IEnumerator Step6() {

        this.transform.position = pos6.transform.position;

        yield return new WaitForSeconds(timeDelay);
        if(beltStart == false || ScriptManager.stopMachine==false){
            stepNo=6;
        }
        else{
            yield return null; //Done
        }

    }
    IEnumerator Step7() {

        this.transform.position = pos7.transform.position;


        yield return new WaitForSeconds(timeDelay);
        if(beltStart == false || ScriptManager.stopMachine==false){
            stepNo=7;
        }
        else{
            yield return null; //Done
        }

    }
    IEnumerator Step8() {
 
        this.transform.position = pos8.transform.position;


        yield return new WaitForSeconds(timeDelay);

        Destroy(gameObject ,0.4f);
    }

    public void StayStrong(float tTime){

        c1 = StartCoroutine(ContinueGameBot());
        c2 = StartCoroutine(ContinueGameTop());

        StopCoroutine(c1);
        StopCoroutine(c2);


        timerDelayTop +=tTime;
        timerDelayBot+=tTime;
        print("stay strong");
        beltStart=true;
        resetTime=true;
        c1 = StartCoroutine(ContinueGameBot());
        c2 = StartCoroutine(ContinueGameTop());


    }



    IEnumerator BuildPlayerMessage (){

            yield return new WaitForSeconds(0.3f);
            PrefabImage.enabled = false;
            cube.SetActive(false);
            botCube.SetActive(false);
            GameObject slot = (GameObject) Instantiate (textGOPrefab);
            slot.transform.parent = this.gameObject.transform;
            slot.GetComponent<RectTransform>().rotation = Quaternion.Euler(0,0,0);
            slot.GetComponent<RectTransform>().localPosition = new Vector3 (0,1,0);
            slot.GetComponent<RectTransform>().localScale = new Vector3 (1,1,1);

    }




    public void Work(){
        print("worked? ////////////////////");
        StartCoroutine(BuildPlayerMessage());
        ScriptManager.stopMachine=true;
        ScriptManager.stopCommentMachine=true;

        if(cube.gameObject!= null){
        cube.SetActive(true);
        cube.SendMessage("TellThemAll");

        }


    }

    public void StopMovement(int stopMov){
        print("working or not///////////?");
        ScriptManager.stopMachine=true;
        topGameObject=stopMov;
        botGameObject=2;
        print(topGameObject);

    }




    IEnumerator ContinueGameBot() {

        yield return new WaitForSeconds(timerDelayBot);//2f
        processStarted=false;
        ScriptManager.stopMachine=false;
        beltStart=false;
        }
    IEnumerator ContinueGameTop() {

        yield return new WaitForSeconds(timerDelayTop);//2f

        topGameObject=0;

    }
}

I’m not sure I understand your code enough. I don’t know what this script is on, nor do I really understand your “chain”.

However, just at a glance my guess is your issue is you’re starting multiple coroutines and that is throwing your chain off. For example, if you drop multiple objects and call the StayStrong method each time, each call will trigger the two coroutines. Then, the coroutines have a small delay, but even when one finishes, there is a second call that may still be yielding and then it triggers when you don’t want it to.

Not sure if that makes sense. But just think that each time you call StayStrong you are creating two more calls to the coroutines and they will each be yielding for 2 secs, which means you could have a couple of ContinueGameBots all yielding and then executing after each other.

The same thing can happen with the coroutines in update. It’s possible you are calling those multiple times in a second, so you may have several copies of those yielding.

Thanks Brathnann, I think that might be the issue, going to see if I can put a condition on each courintine

Beginners in Unity with a problem to solve often reach for coroutines. Now they have two problems to solve.

Consider rewriting your script to not use them. It seems to me the script only needs to know what state it’s in, and when to advance to the next state. A couple of fields will keep track of that — and result in a script that is shorter, simpler, and easier to debug.

1 Like

Hi Joe, what do you mean by “fields”?

Instance variables in your class, sometimes called properties (though technically this isn’t correct for plain old fields). See Fields (C# Programming Guide).

I have updated the code above, also added a clip to show what the problem is. I am in serious desperate mode, its been a week around this specific problem, plz help anyone. Your name will be given to my first born!

i tried to add you on Skype but there is a ton of people with your name pm me with your email?

sent!

What’s your skype id?

sent!

richi_rish my skype id