アニメーションの仕組みではルートモーションを使っても回転後の方向を維持するのが面倒だったので、DOTween を使って作るのが楽だと思いました。以下がコードと、実行している様子です。
C#
1using UnityEngine;
2using DG.Tweening;
3
4public class DiceController : MonoBehaviour
5{
6 [SerializeField] float _duration = 0.5f;
7 [SerializeField] float _edgeLength = 1.4f;
8 [SerializeField] float _rotateAngle = 90f;
9 Sequence _seq;
10
11 void Update()
12 {
13 if (!_seq.IsActive())
14 {
15 float v = Input.GetAxis("Vertical");
16 float h = Input.GetAxis("Horizontal");
17
18 if (h > 0)
19 {
20 Left(true);
21 }
22 else if (h < 0)
23 {
24 Left();
25 }
26 else if (v > 0)
27 {
28 Forward();
29 }
30 else if (v < 0)
31 {
32 Forward(true);
33 }
34 }
35 }
36
37 void Forward(bool reverse = false)
38 {
39 int dir = reverse ? -1 : 1;
40 float humpHeight = (Mathf.Sqrt(_edgeLength * _edgeLength * 2) - _edgeLength) / 2;
41 _seq = DOTween.Sequence();
42 _seq.Append(transform.DOMove(new Vector3(0, humpHeight, dir * _edgeLength / 2), _duration / 2).SetRelative(true));
43 _seq.Join(transform.DORotateQuaternion(Quaternion.Euler(dir * _rotateAngle / 2, 0, 0), _duration / 2).SetRelative(true));
44 _seq.Append(transform.DOMove(new Vector3(0, -1 * humpHeight, dir * _edgeLength / 2), _duration / 2).SetRelative(true));
45 _seq.Join(transform.DORotateQuaternion(Quaternion.Euler(dir * _rotateAngle / 2, 0, 0), _duration / 2).SetRelative(true));
46 _seq.Play();
47 }
48
49 void Left(bool reverse = false)
50 {
51 int dir = reverse ? -1 : 1;
52 float humpHeight = (Mathf.Sqrt(_edgeLength * _edgeLength * 2) - _edgeLength) / 2;
53 _seq = DOTween.Sequence();
54 _seq.Append(transform.DOMove(new Vector3(-1 * dir * _edgeLength / 2, humpHeight, 0), _duration / 2).SetRelative(true));
55 _seq.Join(transform.DORotateQuaternion(Quaternion.Euler(0, 0, dir * _rotateAngle / 2), _duration / 2).SetRelative(true));
56 _seq.Append(transform.DOMove(new Vector3(-1 * dir * _edgeLength / 2, -1 * humpHeight, 0), _duration / 2).SetRelative(true));
57 _seq.Join(transform.DORotateQuaternion(Quaternion.Euler(0, 0, dir * _rotateAngle / 2), _duration / 2).SetRelative(true));
58 _seq.Play();
59 }
60}
使ったアセット/パッケージ
unitypackage
Dice.unitypackage
前述の「使ったアセット/パッケージ」をインポート/インストールした後に unitypackage をインポートすれば前掲動画のシーンがセットアップされます。