最近在弄AI,調試程序的時候總是要調整攝像機的視角。灰常不爽然后自己寫了個腳本。比較習慣Scene窗口下的攝像機操作所以就仿造了一個一樣的操作腳本。
首相我們要知道Scene下的攝像機的操作方式
1.WASD分別控制前后左右的位移,注意:位移是已當前視角為基准的。
2.QE分別控制上下,注意:這個是針對世界坐標的。
3.鼠標右鍵控制自由視角旋轉。(難點)
對於第一條來說,主要的問題就是現在玩家朝向問題。我怎么知道我面向哪里。
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; Debug.Log(MovePos); 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; //Debug.Log(transform.rotation * Vector3.forward + "," + transform.rotation * Vector3.left + "," + transform.rotation * Vector3.right); 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; } }
