Dice Animation and Face Determination

I want to roll a few dice models and be able to determine the face that is UP at the end of the roll on the various dice and use those face values in both JavaScript and/or C# scripts. First, how would you roll dice models in Unity and secondly, can someone give an example of determining which face is up on a die model in JavaScript and C#?

A quick and dirty solution would be to calculate the Vector3.Dot product of the x, y, z axises of your cube against Vector3.up. If a value is (close to) 1 that side is up, if a value is (close to) -1, that side is down (so opposite side is up).

Enough info to build your own code with or do you need a script?

EDIT What the heck, here's a script (the side numbers need to be adjusted to how you've got your dice set up, for me, top = 6, bottom = 1, right side = 4, left side = 3, front side = 5, back side = 2.

The code is in C# but shouldn't be hard to convert to Javascript.

using UnityEngine;
using System.Collections;

public class JDiceSideUp : MonoBehaviour {

    int CalcSideUp() {
    	float dotFwd = Vector3.Dot(transform.forward, Vector3.up);
    	if (dotFwd > 0.99f) return 5;
    	if (dotFwd < -0.99f) return 2;

    	float dotRight = Vector3.Dot(transform.right, Vector3.up);
    	if (dotRight > 0.99f) return 4;
    	if (dotRight < -0.99f) return 3;

    	float dotUp = Vector3.Dot(transform.up, Vector3.up);
    	if (dotUp > 0.99f) return 6;
    	if (dotUp < -0.99f) return 1;

    	return 0;
    }

    void Update() {
    	int side = CalcSideUp();
    	if (side > 0) Debug.Log("Side = " + side);
    }
}

Note that in the above code there is dead zone of 0.99. However unlikely if those values come up the dice value will be 0, which is likely not what you want, change some of the operators to be <= or >= etc..

How you would roll dice would depend on if you're using a physics-based model, determining the result because of the dice bouncing around, or if you want to simulate the rolling to land on a specific number.

If you're going for the physics model, you could do worse than to check out the source code for Rock'n'Roll dice, which I released under the Artistic License about 11 months ago. You can see a video of it here.

Working on a prototype which involves dice, I was having the same problem of getting the 'up' face of the rolled dice. I used the 'dot product' solution, which works pretty well.

I'm now facing the extension of the problem: how to determinate the result of a die with n-faces? eg: D4 (with the resulting face at the bottom), D8, D10, etc.

The configuration of each die is different, and I wonder if another approach would work. Some hints maybe:

  • using different materials for each face?
  • using properties on (mesh) faces?
  • using a top-bottom raycast to the center of the die to get the top-most face. But might not work for non-symetric dice?

Any suggestions?

late answer, but you can also add 6 empty gameobjects, parented under your model. adjust their positions to the middle of each face. After Rolling you check which one has the highest y position in world space. This works also with rolling objects exept a pyramid. You could store them in an array at special indexes, this it is easy to find an according up value. (any number from 0 to 5 for example.)

My best answer for the question of detecting the value of physics-based moving dice with no predetermined value, something I have used, is to put colliders on the faces (as triggers), and detect the collision with the surface upon which you are rolling by labeling or tagging that surface, and checking OnTriggerEnter in a script for that surface. While that gives you a side that IS NOT the value of the roll, it tells you what is facing up. My way entails the following:

  • Put sphere colliders on the center of each face, as triggers, parented to the die itself
  • Encode them in some way with the value that the dice would have if this side was down against the rolling surface. I put it in the name because I started simple with a d4, but a d6 would have to be named for its opposite face.
  • In OnTriggerEnter(), send a message upwards including the face’s value that was triggered.
  • Add a function to a script on the die that receives this message, which takes the face’s values (or however you are encoding it, and to whatever entity you are delegating the knowledge about what to imply from the trigger event)
  • This function should set the die’s “currentValue”
  • The die’s script could also check whether the rigidbody is sleeping, and report that value, by sending a message upwards to a parent object.

The leg work is a little tedious, but the solution is as accurate as you are at labeling them. It avoids using math, as well, and having to figure out that math for a set of Role playing dice.

Sorry I don’t have code, nor do i have a solution for the other question.

You have good answers already, but I will suggest something totally different. Who knows, maybe it gives you some new ideas.

Why don’t you do the other way?

  • Determine the results of each die using Random.
  • Place the dice with their final results up on a staging area away from the camera.
  • Apply random forces to their rigidbodies so that they roll around.
  • Record their movement for a couple of seconds (120 positions and rotations each).
  • Finally, play the recorded movement of the dice backwards to the player’s camera. It will look like the dice are rolling towards the final positions that you determined with Random at the beginning.

This will let you ‘cheat’ somehow. For example, having blessed or cursed dice that have guaranteed results >3 or <4 or that only roll 1, or whatever. :slight_smile: