Rolling the Dice With Unity

No, I’m not talking about taking a chance using Unity to do game development. That decision was made once MS stopped caring about XNA 🙁 (obligatory links here and here on it’s impending demise). I’m talking about having rolling dice in your game. In this case it’s just one die and it’s 2D not 3D. Still, it might prove useful to some people so here we go.

So I’m working on a 2D board game that uses a die to determine the number of squares a player moves. I wanted to show the player something so they’d know the game is rolling a die rather than just generating a random number and showing it. Turns out it’s fairly easy to do using Unity.

First off, I needed some pictures of the 6 sides of a die:

     

I didn’t want to take up any space on the board and also wanted to let the player know in a rather obvious way that it was time to roll the die, so I decided to slide in a panel with the image of the die on it and allow him to tap or click it to start the rolling process. Here’s what I ended up with:

Notice the panel is far off to the left. It’ll slide in from and out to the left. This is done with a simple animation:

At the end of the animation the x position of the panel is set to 0 which, since it’s anchored in the center of the Canvas moves it to the middle of the screen. I do the exact opposite to slide the panel back off the screen in the animation to close the panel, setting the x position to –1000 at the end of the animation. If you’ve never used animations before, there are a ton of resources to help you learn them. As always, your best first step is the Unity site. Here’s a link to the manual section for animations. Here’s a nice tutorial that covers slide UI controls in and out as I’m doing, as well as a ton of other concepts.

Once I had the animations set up, all that was needed was a small amount of code to do the die rolling:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

 

public class DieManager : MonoBehaviour {

 

    public Sprite[] Dice;

 

    private bool _isRolling;

 

    private float _totalTime;
    private float _intervalTime;

 

    private int _curDie;

 

    Image _die;

 

    private bool _dieRolled;

 


	// Use this for initialization
	void Start ()
    {
        Init();
	}

 

    private void Init()
    {
        _totalTime = 0.0f;
        _intervalTime = 0.0f;
        _curDie = 0;
        _dieRolled = false;
        _die = GameObject.Find("DieImage").GetComponent<Image>();
        _die.sprite = Dice[_curDie];
    }

 

	void Update () 
    {
        if (_isRolling)
        {
            _intervalTime += Time.deltaTime;
            _totalTime += Time.deltaTime;

 

            if (_intervalTime >= 0.1f)
            {
                //change die
                _curDie = Globals.Rnd.Next(0, 6);

 

                //set image to selected die
                _die.sprite = Dice[_curDie];

 

                _intervalTime -= 0.1f;
            }

 

            if (_totalTime >= 2.00f)
            { 
                _isRolling = false;
                _dieRolled = true;
            }
        }

 

	}

 

    public void DieImage_Click()
    {
        if(!_dieRolled)
            _isRolling = true;
    }
}

The Dice member holds the 6 images of the die. It’s public as I set them in the Unity UI:

The script is attached to the Canvas object. The die images are then dragged into place from the folder in the game Assets where I’d placed them.

The _isRolling member is used to determine whether or not the time is tracked between frames in order to know when it’s time to change the die image (every 1/10 of a second) or when the die rolling is completed (after 2 seconds).

The _totalTime and _intervalTime members are added to each frame to know when it’s time to change the die image and when the die rolling is completed.

The _curDie member holds the value of the most recently generated number between 0 and 5 (remember kids, arrays are numbered starting at 0, see the screenshot above!) and is the index into the Dice array for displaying the image.

_die is the reference to the Image control in the Panel.

_dieRolled is used to determine if the animation is done for this turn of the game so the player can’t just keep clicking the image to roll again.

The DieImage_Click event is used in an Event Trigger on the DieImage object:

So how does the panel slide in and out since it doesn’t happen automatically? Two simple events for the buttons in the scene:

    public void PanelTestButton_Click()
    {
        GameObject panel = GameObject.Find("DiePanel");
        Animator animator = panel.GetComponent<Animator>();
        animator.Play("DiePanelOpen");
    }

 

    public void PanelOKButton_Click()
    {
        GameObject panel = GameObject.Find("DiePanel");
        Animator animator = panel.GetComponent<Animator>();
        animator.Play("DiePanelClose");
    }

 

I’ve left a bug in the logic as an exercise for the reader. You can only click the die once. It doesn’t reset when you close the panel. How would you solve this? I’ll post a comment later. 🙂

3 Comments

  1. Moutik says:

    hey! awesome tutorial, I did make it work which is a big step for me as a beginner.
    However i’m struggling to make it work more than once.

    I tried to play with the _dieRolled value but couldn’t make it work somehow.
    Any advice you could give to help me figure it out ?
    Cheers

    • Mach X Games says:

      What do you mean by “make it work more than once”? Do you not want the panel to go away after clicking the OK button? If so, simply remove the code in the PanelOKButton_Click method.

  2. sskethan says:

    Thank you for tutorial. I was able to get everything working and the player is able to reroll after clicking the done button. I even added a feature to display how many times the dice has been rolled and a total of the dice rolled. I was wondering if you could show how to add more dice? an option for the player to choose how many dice to roll.

Leave a Reply

You must be logged in to post a comment.