UnityVR.05如何實現VR第一人稱射擊行為
阿新 • • 發佈:2019-02-12
【學習專案為Unity官方的VR Smaples,可以在Asset Store下載】
VR射擊遊戲之中,準心是隨著玩家的頭部轉動進行瞄準的,當準心落在了某個可射擊物件時,再按下開火鍵,即可實現VR遊戲的瞄準射擊行為。在這個過程中,我們要考慮的是,包含玩家血量、得分的一些資訊UI應該是隨著玩家視野的轉動而跟隨變動的,而一些可被射擊的物件則是靜止不動的,下面通過具體的程式碼來講解一下關鍵的地方。
1.讓資訊UI跟隨著攝像機旋轉
想象一下我們需要實現的效果,當玩家站在水平面上時,敵人出現在四面八方,這時候我們通過轉動身體來尋找前後左右的敵人進行射擊。這個過程中,一些得分之類的UI資訊也同步顯示在玩家的視野中。
不過需要注意的是,當玩家進行擡頭和低頭的動作時,如果這些資訊UI也跟隨上下浮動,從遊戲設計上來說,沒有必要,因為我們不需要面對來自頭頂和地面的敵人,同時為了保證遊戲介面的穩定以防玩家不會輕易產生眩暈感,我們可以將這些UI元素的Y軸座標固定不動。
這樣這些UI元素就能夠面對著玩家的身體正面進行轉動,而不是圍繞著玩家的頭部進行旋轉。
下面是我們需要宣告的變數:
我們要實現的效果如上圖所示,武器要隨著攝像機的朝向改變自己的朝向,下面是實現這個行為的具體程式碼: //這個指令碼應該與射擊的武器的父級進行關聯 private void Update() { // 武器父級的朝向插值轉向頭部朝著的方向 transform.rotation = Quaternion.Slerp(transform.rotation, InputTracking.GetLocalRotation(VRNode.Head),
m_Damping * (1 - Mathf.Exp(k_DampingCoef * Time.deltaTime)));
// 武器的位置與攝像機的位置保持一致
transform.position = m_CameraTransform.position;
// 通過準心與武器的位置來確定武器的朝向
Quaternion lookAtRotation = Quaternion.LookRotation (m_Reticle.ReticleTransform.position - m_GunContainer.position);
// 武器的朝向向著朝準心的方向進行插值旋轉
m_GunContainer.rotation = Quaternion.Slerp (m_GunContainer.rotation, lookAtRotation,
m_GunContainerSmoothing * Time.deltaTime);
}
InputTracking.GetLocalRotation(VRNode.Head) 根據VR頭部裝置的轉向,返回一個四元數
通過以上兩步我們就可以實現VR中第一人稱的射擊行為,具體的例項可以參看官方示例VR Samples中的Shooter360場景。
在遊戲開始執行時,在Start方法中,儲存下攝像機和UI元素的距離,用來在遊戲時,UI元素旋轉時能和攝像機的距離保持不變。[SerializeField] private bool m_LookatCamera = true; // UI元素是否應該面對著攝像機 [SerializeField] private Transform m_UIElement; // 引用這些要旋轉UI元素 [SerializeField] private Transform m_Camera; // 引用攝像機 [SerializeField] private bool m_RotateWithCamera; // UI元素是否應該隨著攝像機旋轉 [SerializeField] private float m_FollowSpeed = 10f; // UI元素的跟隨速度 private float m_DistanceFromCamera; // UI元素和攝像機的保持距離
private void Start ()
{
m_DistanceFromCamera = Vector3.Distance (m_UIElement.position, m_Camera.position);
}
下面是具體的實現方法:
Vector3.ProjectOnPlane 將向量投影到由以另一個向量為法線定義的平面上 2.讓武器跟隨者玩家的視野改變朝向private void Update() { if(m_LookatCamera) //UI元素的自身,面對著攝像機保持朝向 m_UIElement.rotation = Quaternion.LookRotation(m_UIElement.position - m_Camera.position); if (m_RotateWithCamera) { //相機朝向的方向向量在水平面上的投影 Vector3 targetDirection = Vector3.ProjectOnPlane (m_Camera.forward, Vector3.up).normalized; // 計算出UI元素要移動到的目標位置 Vector3 targetPosition = m_Camera.position + targetDirection * m_DistanceFromCamera; // UI元素由當前點向目標點進行插值移動 targetPosition = Vector3.Lerp(m_UIElement.position, targetPosition, m_FollowSpeed * Time.deltaTime); // UI元素在XZ水平面上進行旋轉,Y軸座標值保持不變 targetPosition.y = m_UIElement.position.y; // Set the UI's position to the calculated target position. m_UIElement.position = targetPosition; } }
我們要實現的效果如上圖所示,武器要隨著攝像機的朝向改變自己的朝向,下面是實現這個行為的具體程式碼: //這個指令碼應該與射擊的武器的父級進行關聯 private void Update() { // 武器父級的朝向插值轉向頭部朝著的方向 transform.rotation = Quaternion.Slerp(transform.rotation, InputTracking.GetLocalRotation(VRNode.Head),