1. 程式人生 > >Unity滑鼠控制相機上下左右環視360度旋轉(Quaternion.AngleAxis)

Unity滑鼠控制相機上下左右環視360度旋轉(Quaternion.AngleAxis)

之前實現的是相機的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