yotiky Tech Blog

とあるエンジニアの備忘録

Unity - マウスドラッグで対象を中心にカメラを回転させる(三人称視点)

目次

オブジェクトを中心にカメラを回転させる

対象のGameObjectを中心にカメラをマウスドラッグで回転(三人称視点)させるサンプルスクリプト

f:id:yotiky:20200805021009g:plain

public class CameraRotator3rdPersonPov : MonoBehaviour
{
    public GameObject playerObject;
    public Vector2 rotationSpeed;
    public bool reverse;

    private Camera mainCamera;
    private Vector2 lastMousePosition;

    void Start()
    {
        mainCamera = Camera.main;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            lastMousePosition = Input.mousePosition;
        }
        else if (Input.GetMouseButton(0))
        {
            if (!reverse)
            {
                var x = (lastMousePosition.x - Input.mousePosition.x);
                var y = (Input.mousePosition.y - lastMousePosition.y);

                if (Mathf.Abs(x) < Mathf.Abs(y))
                    x = 0;
                else
                    y = 0;

                var newAngle = Vector3.zero;
                newAngle.x = x * rotationSpeed.x;
                newAngle.y = y * rotationSpeed.y;

                mainCamera.transform.RotateAround(playerObject.transform.position, Vector3.up, newAngle.x);
                mainCamera.transform.RotateAround(playerObject.transform.position, transform.right, newAngle.y);
                lastMousePosition = Input.mousePosition;
            }
            else
            {
                var x = (Input.mousePosition.x - lastMousePosition.x);
                var y = (lastMousePosition.y - Input.mousePosition.y);

                if (Mathf.Abs(x) < Mathf.Abs(y)) 
                    x = 0; 
                else 
                    y = 0; 

                var newAngle = Vector3.zero;
                newAngle.x = x * rotationSpeed.x;
                newAngle.y = y * rotationSpeed.y;

                mainCamera.transform.RotateAround(playerObject.transform.position, Vector3.up, newAngle.x);
                mainCamera.transform.RotateAround(playerObject.transform.position, transform.right, newAngle.y);
                lastMousePosition = Input.mousePosition;
            }
        }
    }
}

操作が難しいので、x と y の小さい方を 0 で上書きして、移動量が多い方のみを有効値としています。同時に回転させたい場合は当該箇所をコメントアウトして下さい。

動くオブジェクトに追従する

上記は動かないオブジェクトですが、対象のGameObjectが移動する時に追従させる場合は以下のコードを追加します。(必要な処理だけ抜粋)

    private Vector3 lastTargetPosition;

    void Update()
    {
        mainCamera.transform.position += targetObject.transform.position - lastTargetPosition;
        lastTargetPosition = targetObject.transform.position;

        // 最初のコードと同じため省略
    }

f:id:yotiky:20200805022706g:plain

回転可能な角度を制限する

続いて回転できる角度に制限を設ける場合です。最初のサンプルコードのnewAngleを求めた後に以下のコードを追加します。(必要な処理だけ抜粋

    private float maxAngle = 90;
    private Vector3 totalAngle = Vector3.zero;

    void Update()
    {
                // 省略

                var newAngle = Vector3.zero;
                newAngle.x = x * rotationSpeed.x;
                newAngle.y = y * rotationSpeed.y;

                if (maxAngle < totalAngle.x + newAngle.x)
                    newAngle.x = maxAngle - totalAngle.x;
                if (totalAngle.x + newAngle.x < -maxAngle)
                    newAngle.x = -maxAngle - totalAngle.x;

                totalAngle.x += newAngle.x;

                // 省略
    }