Unityカメラ自由移動スクリプト

WSADの移動方向、マウスの右ボタンの回転角度、ズームを実現するスクロールホイールを実現します。

その前に、いくつかのわかりにくい点を明確にしましょう。

1: Transform.forwardは、Transform コンポーネントの Vector3 型属性で、ワールド座標系におけるゲームオブジェクトの向き、つまり「正面方向」を表し、その値は (0,0,1) です。オブジェクトの方向を表します。X 軸方向は通常、移動、回転、光線検出などのシナリオなど、ゲーム オブジェクトが移動する方向を計算するために使用されます。

2: Transform.Rightの数式は (1, 0, 0) です。オブジェクトの X 軸方向、またはその右方向を表します。

これらはすべて単位ベクトルであり、通常は方向の計算にのみ使用されることに注意してください。

3:Input.GetAxis("水平")とInput.GetAxis("垂直")、input.GetAxis("マウスX")

それぞれ水平入力と垂直入力を取得する関数で、現在の水平方向の入力状態を-1から1までの浮動小数点数で返します。

たとえば、Input.GetAxis("Mouse X")水平方向のマウスの動きを浮動小数点数で返します。マウスが右に移動すると正の値が返され、マウスが左に移動すると負の値が返されます。マウスが動いていない場合は 0 を返します

Input.GetAxis("Mouse ScrollWheel")、前方スクロールは正の数、後方スクロールは負の数

4: オイラー角と四元数

一体の回転はオイラー角を利用するもので、オイラー角とは3軸を基準とし、物体の回転状態を異なる軸(通常はXYZ、ZYX、ZXYなど)の周りの回転角度で表します。回転シーケンス。ただし、オイラー角にはジンバル ロックの問題が発生します。つまり、特定のケースでは 2 つの軸の回転が一致し、回転計算が異常になります。

クォータニオンは、クォータニオンの定義と操作によって回転を実現しますが、クォータニオンは実際には 1 つの実部と 3 つの虚数部を含む四元数です。これらは、ジンバル ロックの問題を回避するためにオイラー角とは異なる方法で定義されており、回転順序は回転結果に影響しません。クォータニオンは補間演算を通じてスムーズな回転を実現することもできるため、連続回転が必要な状況に適しています。

コードを 3 つの部分に分割しました

最初のモジュールは前後左右を制御する WSAD で、このセクションは比較的単純で、V3 タイプの移動方向を直接定義し、Translate を使用します。

2 番目のモジュールは、QE を使用して上下の画角を制御し、変数 upDown を定義し、ボタンを押すたびに 1 を変更し、その位置をカメラの位置に直接割り当てます。

3 番目のモジュールは、マウスの右ボタンを使用して回転し、2 つの回転ベクトル、rotateX、rotateY、Y 方向の回転制限 minAngle と maxAngle を設定し、ベクトルと速度をカメラのオイラー角に追加します。

問題があります。最初にデバッグを開始したとき、初めてマウスの右ボタンをクリックして回転すると、画面が飛び続けました。最終的に、GPT の助けを借りて、問題は解決されました。愛のGPT

using UnityEngine;
public class CameraController : MonoBehaviour
{
    //WSAD相机移动速度
    public float moveSpeed = 1.0f;
    //相机当前移动方向
    private Vector3 moveDirection;

    //QE相机的目标高度
    private float upDistance;
    public float upSpeed = 0.2f;

    //鼠标右键控制旋转
    private float rotateX,rotateY;
    public float sensitivity =0.5f;
    //控制鼠标在Y方向上的限值
    public float minAngle = -90f;
    public float maxAngle = 90f;
    //记录之前的欧拉角,避免跳屏
    private Vector3 currentRotation,lastPosition;

    //鼠标滚轮控制缩放
    public float zoomSpeed = 10f;
    private float zoomDistance = 0f;

    private void Start()
    {
            currentRotation = transform.eulerAngles;
    }
    void Update()
    {
        // 使用WSAD控制相机前后左右移动比较简单,直接获取当前的移动方向,然后使用Translate移动即可
        {
            moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            transform.Translate(moveDirection * moveSpeed * Time.deltaTime);
        }

        //使用QE控制相机的上下,使用unDown参数进行单位变化
        {
            if (Input.GetKey(KeyCode.Q))
            {
                upDistance -= upSpeed * Time.deltaTime;
                transform.Translate(transform.up * upDistance, Space.World);
            }
            else if(Input.GetKeyUp(KeyCode.Q))
            {
                upDistance = 0;
            }
            if (Input.GetKey(KeyCode.E))
            {
                upDistance += upSpeed * Time.deltaTime;
                transform.Translate(transform.up * upDistance, Space.World);
            }
            else if(Input.GetKeyUp(KeyCode.E))
            {
                upDistance = 0;
            }
        }

        //使用鼠标右键来控制相机旋转
        //Mouse X,向右移动返回正值,Mouse Y,向上移动鼠标为正值
        {
            if (Input.GetMouseButtonDown(1))
            {
                // 记录当前的欧拉角
                //currentRotation = transform.eulerAngles;
                //记录鼠标位置
                lastPosition = Input.mousePosition;
            }
            if (Input.GetMouseButton(1))
            {
                //设置偏移量
                Vector3 offset = Input.mousePosition - lastPosition;
                rotateX += offset.x * sensitivity;
                rotateY -= offset.y * sensitivity;

                //给Y方向的旋转加上限值函数
                rotateY = Mathf.Clamp(rotateY, minAngle, maxAngle);
                //改变当前的欧拉角
                transform.eulerAngles = new Vector3(rotateY, rotateX, 0f);

                // 将保存的欧拉角重新赋值回去
                transform.eulerAngles += currentRotation;
                lastPosition = Input.mousePosition;
            }
        }
        //使用滚轮来控制物体的缩放
        {
            //获取滚轮的滚动幅度和方向
            zoomDistance += Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
            //使用限值函数来限定缩放的范围
            zoomDistance = Mathf.Clamp(zoomDistance, -10f, 10f);
            //最后定位
            transform.position = transform.position + transform.forward * Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
        }
    }
}

コードを直接コピーし、カメラに掛けて実行してください。

Supongo que te gusta

Origin blog.csdn.net/leikang111/article/details/130362335
Recomendado
Clasificación