Cubeを接地した状態で回転させる方法について

少し前にTwitterで「箱を角が設置した状態で回すのってどうやってるのか?」と言う書き込みを見て、
自分自身も少し気になってきたので調べてみた。

実装するにあたっては回転軸の位置を指定しながら回転させる必要があるが、
こちら結論から言ってしまうとTransform.RotateAround(Vector3 point, Vector3 axis, float angle);を使う事で実装する事が出来た。

Transform.RotateAround

今回テストとして実装した物としては以下の様な挙動となる。

Rotate.gif

実装時のテストコードはこちら。
こちらをCubeにアタッチする事で動作可能。

using System.Collections;
using UnityEngine;

public class Test : MonoBehaviour
{
    const float RotatingSpeed = 0.2f;
    const float RotatingAngle = 90f;
    Vector3 halfSize;
    float time = 0f;
    Vector3 axis = Vector3.zero;
    Vector3 point = Vector3.zero;

    void Awake()
    {
        this.halfSize = this.transform.localScale / 2f;
    }

    void Update()
    {
        if (this.point != Vector3.zero) { return; }
        if (Input.GetKey(KeyCode.UpArrow))
        {
            this.axis = Vector3.right;
            this.point = this.transform.position + new Vector3(0f, -this.halfSize.y, this.halfSize.z);
        }
        else if (Input.GetKey(KeyCode.DownArrow))
        {
            this.axis = Vector3.left;
            this.point = this.transform.position + new Vector3(0f, -this.halfSize.y, -this.halfSize.z);
        }
        else if (Input.GetKey(KeyCode.LeftArrow))
        {
            this.axis = Vector3.forward;
            this.point = this.transform.position + new Vector3(-this.halfSize.x, -this.halfSize.y, 0f);
        }
        else if (Input.GetKey(KeyCode.RightArrow))
        {
            this.axis = Vector3.back;
            this.point = this.transform.position + new Vector3(this.halfSize.x, -this.halfSize.y, 0f);
        }
        if (this.point != Vector3.zero)
        {
            StartCoroutine(this.StartRotate());
        }
    }

    IEnumerator StartRotate()
    {
        float nowAngle = 0f;
        float addAngle = (RotatingAngle / (RotatingSpeed * 60f));
        while (this.time <= RotatingSpeed)
        {
            nowAngle += addAngle;
            if (nowAngle <= RotatingAngle)
            {
                this.transform.RotateAround(this.point, this.axis, addAngle);
            }
            this.time += Time.deltaTime;
            yield return null;
        }
        this.time = 0f;
        this.axis = this.point = Vector3.zero;
        yield break;
    }
}

https://gist.github.com/mao-test-h/42d580978b5fabccbe4a6a0e12b58f32

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.