1. 程式人生 > >Unity Game視窗中還原Scene視窗攝像機操作

Unity Game視窗中還原Scene視窗攝像機操作

最近在弄AI,除錯程式的時候總是要調整攝像機的視角。灰常不爽然後自己寫了個指令碼。比較習慣Scene視窗下的攝像機操作所以就仿造了一個一樣的操作指令碼。

首相我們要知道Scene下的攝像機的操作方式

  • WASD分別控制前後左右的位移,注意:位移是已當前視角為基準的。
  • QE分別控制上下,注意:這個是針對世界座標的。
  • 滑鼠右鍵控制自由視角旋轉。(難點)

對於第一條來說,主要的問題就是現在玩家朝向問題。我怎麼知道我面向哪裡。

Vector3 Face = transform.rotation * Vector3.forward;
Face = Face.normalized;

這段程式碼就是玩家的朝向,把目前玩家的旋轉角度乘上向量的前方,就是玩家的面朝方向,因為我們就要方向,所以單位向量化了。

下面就是關於第一條的控制方式。

        Vector3 Face = transform.rotation * Vector3.forward;
        Face = Face.normalized;

        Vector3 Left = transform.rotation * Vector3.left;
        Left = Left.normalized;

        Vector3 Right = transform.rotation * Vector3.right;
        Right = Right.normalized;

        if (Input.GetKey
("w")) { transform.position += Face * Speed * Time.deltaTime; } if (Input.GetKey("a")) { transform.position += Left * Speed * Time.deltaTime; } if (Input.GetKey("d")) { transform.position += Right * Speed * Time.deltaTime
; } if (Input.GetKey("s")) { transform.position -= Face * Speed * Time.deltaTime; }

第二條就不用多說了吧。上程式碼

        if (Input.GetKey("q"))
        {
            transform.position -= Vector3.up * Speed * Time.deltaTime;
        }

        if (Input.GetKey("e"))
        {
            transform.position += Vector3.up * Speed * Time.deltaTime;
        }

最難的第三條。心思了半天有兩種解決方法,但都有缺陷

  1. 統一轉換成Vector來計算
  2. 統一轉換成Quaternion來計算

優缺點:

  1. 旋轉時有卡頓不流暢,但是到位快
  2. 旋轉時比第一種流暢一些也有些許卡頓,但到位不快甚至不到位。

對於這兩種方式,主要的思路都是取滑鼠滑動的單位向量然後乘以速度。

這兩種都設計到一個比較坑爹的問題。

滑鼠向上下滑動時:

  • 針對滑鼠來說是y軸加減
  • 針對rotation來說是x軸減加

同理滑鼠左右滑動時:

  • 針對滑鼠來說是x軸減加
  • 針對rotation來說是y軸減加

所以這段程式碼就很重要

            //_Rot是物體當前rotation值,MovePos是修改的值,最後得旋轉後的值
            _Rot.x -= MovePos.y * 2; //*2是可以調節的速度,越大越快
            _Rot.y += MovePos.x * 2;
            _Rot.z += MovePos.z * 2

然後對於第一種方式全部變為Vector處理我們就會用到Transform.eulerAngles;
程式碼為

    Vector3 Save = Input.mousePosition;
    Vector3 MovePos = Save - MouseDownPos;
    MovePos = MovePos.normalized;
    Vector3 _Rot = transform.rotation.eulerAngles;
    _Rot.x -= MovePos.y * 2;
    _Rot.y += MovePos.x * 2;
    _Rot.z += MovePos.z * 2;
    transform.eulerAngles = _Rot;
    MouseDownPos = Save;

對於第二種方式全部變為Quaternion處理我們用Quaternion.Slerp
程式碼為

    Vector3 Save = Input.mousePosition;
    Vector3 MovePos = Save - MouseDownPos;
    MovePos = MovePos.normalized;
    Vector3 _Rot = transform.rotation.eulerAngles;
    _Rot.x -= MovePos.y * 2;
    _Rot.y += MovePos.x * 2;
    _Rot.z += MovePos.z * 2;
    Quaternion MoveRot = Quaternion.Euler(_Rot);
    transform.rotation = Quaternion.Slerp(transform.rotation, MoveRot, Time.deltaTime * 30);
    MouseDownPos = Save;

最後給完整的Update程式碼

    private float Speed = 5;
    private Vector3 MouseDownPos;

    void Update ()
    {
        Vector3 Face = transform.rotation * Vector3.forward;
        Face = Face.normalized;

        Vector3 Left = transform.rotation * Vector3.left;
        Left = Left.normalized;

        Vector3 Right = transform.rotation * Vector3.right;
        Right = Right.normalized;

        if (Input.GetMouseButtonDown(1))
        {
            MouseDownPos = Input.mousePosition;
        }

        if (Input.GetMouseButton(1))
        {
            //Vector處理
            Vector3 Save = Input.mousePosition;
            Vector3 MovePos = Save - MouseDownPos;
            MovePos = MovePos.normalized;
            Vector3 _Rot = transform.rotation.eulerAngles;
            _Rot.x -= MovePos.y * 2;
            _Rot.y += MovePos.x * 2;
            _Rot.z += MovePos.z * 2;
            transform.eulerAngles = _Rot;
            Debug.Log(MovePos);
            MouseDownPos = Save;

            //Quaternion處理
            //Vector3 Save = Input.mousePosition;
            //Vector3 MovePos = Save - MouseDownPos;
            //MovePos = MovePos.normalized;
            //Vector3 _Rot = transform.rotation.eulerAngles;
            //_Rot.x -= MovePos.y * 2;
            //_Rot.y += MovePos.x * 2;
            //_Rot.z += MovePos.z * 2;
            //Quaternion MoveRot = Quaternion.Euler(_Rot);
            //transform.rotation = Quaternion.Slerp(transform.rotation, MoveRot, Time.deltaTime * 30);
            //MouseDownPos = Save;
        }

        if (Input.GetKey("w"))
        {
            transform.position += Face * Speed * Time.deltaTime;
        }

        if (Input.GetKey("a"))
        {
            transform.position += Left * Speed * Time.deltaTime;
        }

        if (Input.GetKey("d"))
        {
            transform.position += Right * Speed * Time.deltaTime;
        }

        if (Input.GetKey("s"))
        {
            transform.position -= Face * Speed * Time.deltaTime;
        }

        if (Input.GetKey("q"))
        {
            transform.position -= Vector3.up * Speed * Time.deltaTime;
        }

        if (Input.GetKey("e"))
        {
            transform.position += Vector3.up * Speed * Time.deltaTime;
        }

    }