Cube をスクリプトで回転させるときの覚書。
基本的に Quaternion を弄るべきではないみたい。
複数軸の回りを続けて回転させるとものすごく複雑になる。
その代わりに transform.Rotate() を使うのがいい。
移動と回転をコルーチンで徐々に行うことによってそれっぽく見せることもできる。
上下左右キー(アローキー)を押したらその方向に回転するスクリプトは以下のようになる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public GameObject cube; public int rollFrame = 6; private bool isRolling = false; void Update () { if(!isRolling){ //回ってなければキー入力待ち if (Input.GetKey (KeyCode.UpArrow)) { StartCoroutine(CubeRolling( cube.transform.position, cube.transform.position+Vector3.forward, new Vector3(90, 0, 0) )); } else if (Input.GetKey (KeyCode.DownArrow)) { StartCoroutine(CubeRolling( cube.transform.position, cube.transform.position+Vector3.back, new Vector3(-90,0,0) )); } else if (Input.GetKey (KeyCode.RightArrow)) { StartCoroutine(CubeRolling( cube.transform.position, cube.transform.position+Vector3.right, new Vector3(0,0,-90) )); } else if (Input.GetKey (KeyCode.LeftArrow)) { StartCoroutine(CubeRolling( cube.transform.position, cube.transform.position+Vector3.left, new Vector3(0,0,90) )); } } } IEnumerator CubeRolling(Vector3 sv,Vector3 ev,Vector3 r){ isRolling =true; for(int i=1;i<=rollFrame;i++){ cube.transform.position = Vector3.Lerp(sv,ev,(float)i/rollFrame); cube.transform.Rotate(r/rollFrame,Space.World); yield return null; } isRolling =false; } |
これを実際に動かすと以下のようになる。
それっぽいけど角が少し地面に埋まるのが気になる。
Vector3.Leap の代わりに Vector3.Slerp を使うと中心(0, 0.5, 0)からの移動のみ角が沈まなくなった。この理由はよくわからないけど使えないため没。
Cubeの回転を分割しつつ、三角関数でポジションを決めるように修正。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
public GameObject cube; public int rollFrame = 6; private bool isRolling = false; void Update () { if(!isRolling){ //回ってなければキー入力待ち if (Input.GetKey (KeyCode.UpArrow)) { StartCoroutine(CubeRolling( cube.transform.position, Vector3.forward, new Vector3(90, 0,0) )); } else if (Input.GetKey (KeyCode.DownArrow)) { StartCoroutine(CubeRolling( cube.transform.position, Vector3.back, new Vector3(-90,0,0) )); } else if (Input.GetKey (KeyCode.RightArrow)) { StartCoroutine(CubeRolling( cube.transform.position, Vector3.right, new Vector3(0,0,-90) )); } else if (Input.GetKey (KeyCode.LeftArrow)) { StartCoroutine(CubeRolling( cube.transform.position, Vector3.left, new Vector3(0,0,90) )); } } } IEnumerator CubeRolling(Vector3 sv,Vector3 mv,Vector3 r){ isRolling =true; for(int i=1;i<=rollFrame;i++){ float _r = 1f; float _th = Mathf.Lerp(0, Mathf.PI / 2f, (float)i/rollFrame); float _x = mv.x * _r * (Mathf.Cos (45f * Mathf.Deg2Rad) - Mathf.Cos (45f * Mathf.Deg2Rad + _th)); float _y = _r * (Mathf.Sin(45f * Mathf.Deg2Rad + _th) - Mathf.Sin (45f * Mathf.Deg2Rad)); float _z = mv.z * _r * (Mathf.Cos (45f * Mathf.Deg2Rad) - Mathf.Cos (45f * Mathf.Deg2Rad + _th)); cube.transform.position = new Vector3(sv.x + _x, sv.y + _y, sv.z + _z); cube.transform.Rotate(r/rollFrame,Space.World); yield return null; } isRolling =false; } |
これで角が沈まず自然に回転できるようになった。
けどなんか動きがウキウキしているように見える。なぜだろう。