Unity滑鼠控制相機上下左右環視360度旋轉(Quaternion.AngleAxis)
阿新 • • 發佈:2018-12-10
之前實現的是相機的360度旋轉,用的是LocalEulerAngle,這一篇文章實現用的是Quaternion.AngleAxis,這個方法將繞某個軸旋轉的角度轉為四元數
目前的四元數=初始的四元數*繞X軸轉的四元數*繞Y軸轉的四元數
理解也比較好理解,就是繞某個軸旋轉的角度,轉換為四元數,然後將轉換後的四元數*初始的四元數=最新的四元數
using UnityEngine; using System.Collections; using System.Collections.Generic; public class SmoothMouseLook : MonoBehaviour { public float sensitivity = 4.0f; [HideInInspector] public float sensitivityAmt = 4.0f;//actual sensitivity modified by IronSights Script private float minimumX = -360f; private float maximumX = 360f; private float minimumY = -85f; private float maximumY = 85f; [HideInInspector] public float rotationX = 0.0f; [HideInInspector] public float rotationY = 0.0f; [HideInInspector] public float inputY = 0.0f; public float smoothSpeed = 0.35f; private Quaternion originalRotation; private Transform myTransform; [HideInInspector] public float recoilX;//non recovering recoil amount managed by WeaponKick function of WeaponBehavior.cs [HideInInspector] public float recoilY;//non recovering recoil amount managed by WeaponKick function of WeaponBehavior.cs void Start(){ if (rigidbody){rigidbody.freezeRotation = true;} myTransform = transform;//cache transform for efficiency originalRotation = myTransform.localRotation; //sync the initial rotation of the main camera to the y rotation set in editor Vector3 tempRotation = new Vector3(0,Camera.main.transform.eulerAngles.y,0); originalRotation.eulerAngles = tempRotation; sensitivityAmt = sensitivity;//initialize sensitivity amount from var set by player // Hide the cursor Screen.showCursor = false; } void Update(){ if(Time.timeScale > 0 && Time.deltaTime > 0){//allow pausing by setting timescale to 0 //Hide the cursor Screen.lockCursor = true; Screen.showCursor = false; // Read the mouse input axis rotationX += Input.GetAxisRaw("Mouse X") * sensitivityAmt * Time.timeScale;//lower sensitivity at slower time settings rotationY += Input.GetAxisRaw("Mouse Y") * sensitivityAmt * Time.timeScale; //reset vertical recoilY value if it would exceed maximumY amount if(maximumY - Input.GetAxisRaw("Mouse Y") * sensitivityAmt * Time.timeScale < recoilY){ rotationY += recoilY; recoilY = 0.0f; } //reset horizontal recoilX value if it would exceed maximumX amount if(maximumX - Input.GetAxisRaw("Mouse X") * sensitivityAmt * Time.timeScale < recoilX){ rotationX += recoilX; recoilX = 0.0f; } rotationX = ClampAngle (rotationX, minimumX, maximumX); rotationY = ClampAngle (rotationY, minimumY - recoilY, maximumY - recoilY); inputY = rotationY + recoilY;//set public inputY value for use in other scripts Quaternion xQuaternion = Quaternion.AngleAxis (rotationX + recoilX, Vector3.up); Quaternion yQuaternion = Quaternion.AngleAxis (rotationY + recoilY, -Vector3.right); //smooth the mouse input myTransform.rotation = Quaternion.Slerp(myTransform.rotation , originalRotation * xQuaternion * yQuaternion, smoothSpeed * Time.smoothDeltaTime * 60 / Time.timeScale); //lock mouselook roll to prevent gun rotating with fast mouse movements myTransform.rotation = Quaternion.Euler(myTransform.rotation.eulerAngles.x, myTransform.rotation.eulerAngles.y, 0.0f); }else{ //Show the cursor Screen.lockCursor = false; Screen.showCursor = true; } } //function used to limit angles public static float ClampAngle (float angle, float min, float max){ angle = angle % 360; if((angle >= -360F) && (angle <= 360F)){ if(angle < -360F){ angle += 360F; } if(angle > 360F){ angle -= 360F; } } return Mathf.Clamp (angle, min, max); } }
FR:海濤高軟(Hunk Xu) QQ技術交流群:386476712