Check when multiple coroutines are all done

Viewed 43

So I am making a dice rolling game, every turn the game generates between 1 and 3 dice that "roll" with a coroutine.

I am trying to find a way to check when all the dice are done rolling to do something.

My dice code (attached to each dice object created):

public class Dice : MonoBehaviour {

    // Array of dice sides sprites to load from Resources folder
    public Sprite[] diceSides;
    public GameObject DiceObject;
    public int finalSide = 0;
    public bool doneRolling = false;

    // Reference to sprite renderer to change sprites
    private SpriteRenderer rend;

    public  void Awake() {
    suspect = GameObject.Find("suspect");
    }
    // Use this for initialization
    private void Start () {

        // Assign Renderer component
        rend = GetComponent<SpriteRenderer>();

    }
    
    // If you left click over the dice then RollTheDice coroutine is started
    public void Rolling()
    {
        DiceObject.SetActive(true);
        StartCoroutine("RollTheDice");
    }

    // Coroutine that rolls the dice
    private IEnumerator RollTheDice()
    {
        // Variable to contain random dice side number.
        // It needs to be assigned. Let it be 0 initially
        int randomDiceSide = 0;

        // Final side or value that dice reads in the end of coroutine

        // Loop to switch dice sides ramdomly
        // before final side appears. 20 iterations here.
        for (int i = 0; i <= 20; i++)
        {
            // Pick up random value from 0 to 5 (All inclusive)
            randomDiceSide = Random.Range(0, 5);

            // Set sprite to upper face of dice from array according to random value
            this.GetComponent<Image>().sprite = diceSides[randomDiceSide];

            // Pause before next iteration
            yield return new WaitForSeconds(0.05f);
            doneRolling = true;
        }

        // Assigning final side so you can use this value later in your game
        // for player movement for example
        finalSide = randomDiceSide + 1;

    }
}

Now what would be the best way to check when all the dice created are done rolling and trigger another script at that time?

I was thinking about creating another game object that would be a parent of all the dice and do something like:

public class diceRollerCheck : MonoBehaviour
{

    public void checkIfDiceAreDoneRolling(){
        allDiceAreDone = false;
        while(allDiceAreDone == false){
            foreach (Transform child in this) {
                if (child.GetComponent<Dice>().doneRolling == false){
                    allDiceAreDone = false;
                }
                else{
                    allDiceAreDone = true;
                }
        }
    }
}

(This obviously doesn't work but that's the idea)

1 Answers

You can create an action or event on Dice.cs that invokes on same time with doneRolling = true;

Then on DiceRollerCheck.cs, you can create a list of dice like List or any data structure that you think is the best. And you can get all dices on Start() method with findobjectsoftype or if you instantiate dices in runtime force Dice.cs to find DiCeRoller.cs and add itselt to list.

and then subscribe every dice.cs doneRolling event with a method you created in Dicerollercheck.cs where you gonna count doneRolling and number of dice elements, and count equal to number of dice you have then it means all dices are donerolling.

Related