今回は、Untiyでサイコロを実装してみます。
実際のサイコロに近い感じの3Dで実装してみます。
はじめに
2Dヴァージョンのサイコロは下記。
Unityのバージョンは2021.3.3f1です。
サイコロの画像はBlenderで簡単に作成したものを利用しています。アセットストアなどからフリーで手に入れてもOK。
実装開始
まずはサイコロをUnityに取り込み。

次に、3DオブジェクトからPlaneを追加、サイコロが転がる地面ですね。

取り込んだサイコロを追加、スケールと位置を変更して地面の少し上に配置します。

サイコロにRigidbodyとBoxColliderをアタッチ。

摩擦・跳ね返り
Physic Materialを追加して、サイコロの動きを制御します。

サイコロのマテリアルにセット。

試しに、サイコロのrotationを適当に変更して実行すると、地面に落ちてコロコロと転がります。動きを変えたい場合は、PhysicMaterialのFrictionやBouncinessを調整。

下記スクリプトを作成して、サイコロにアタッチすればランダムにすることが出来ます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DiceRoll : MonoBehaviour { private Rigidbody _rb; void Start() { _rb = GetComponent<Rigidbody>(); Vector3 rota = new Vector3(Random.Range(0, 100), Random.Range(0, 100), Random.Range(0, 100)); transform.Rotate(rote); }
トルクで実装
Rotationを変更することでサイコロの向きをランダムに出来ますが、サイコロが落ちる時にサイコロ感がないので、AddTorqueを使って更にサイコロっぽくします。
スクリプトは下記に変更。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DiceRoll : MonoBehaviour { private Rigidbody _rb; void Start() { _rb = GetComponent<Rigidbody>(); Vector3 torq = new Vector3(Random.Range(0, 100), Random.Range(0, 100), Random.Range(0, 100)); _rb.AddTorque(torq); } }
Startで実装していますが、連続でサイコロを振る場合はUpdateで実装。上方向に力を加えたり、トルクの値の範囲を変更して調整するともっと良い感じになります。
サイコロの目の判定
次にサイコロが止まった時の目の判定をしていきます。
いくつか方法がありますが、地面についた時のサイコロのrotationのX,Zの値で判定する方法(X=0,Z=0の時は5、X=90の時は6など)が簡単な一つの方法だと思います。
衝突判定で判定
今回はサイコロの面に衝突を追加して目の判定をします。
サイコロの配下に3Dオブジェクトのスフィアを追加。

面の中心部分にセット。下記の場合は3の面なので名前を3にしておきます。

同じように全ての面にセット。

空のオブジェクトを追加して、DiceNumManagementとします。

地面に合わせてボックスコライダーをセット。

下記スクリプトを作成してアタッチします。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DiceNumManaagement : MonoBehaviour { [SerializeField] private Rigidbody _rb; private void OnTriggerStay(Collider col) { if (_rb.IsSleeping()) { switch (col.gameObject.name) { case "1": Debug.Log("6"); break; case "2": Debug.Log("5"); break; case "3": Debug.Log("4"); break; case "4": Debug.Log("3"); break; case "5": Debug.Log("2"); break; case "6": Debug.Log("1"); break; } } } }
変数のリジッドボディにはサイコロをセット。

サイコロが止まった時、地面とぶつかっている面が分かるため、その反対側がサイコロの目と言う感じでdebuglogで出力しています。