1. 程式人生 > >UnityVR.05如何實現VR第一人稱射擊行為

UnityVR.05如何實現VR第一人稱射擊行為

【學習專案為Unity官方的VR Smaples,可以在Asset Store下載】 VR射擊遊戲之中,準心是隨著玩家的頭部轉動進行瞄準的,當準心落在了某個可射擊物件時,再按下開火鍵,即可實現VR遊戲的瞄準射擊行為。在這個過程中,我們要考慮的是,包含玩家血量、得分的一些資訊UI應該是隨著玩家視野的轉動而跟隨變動的,而一些可被射擊的物件則是靜止不動的,下面通過具體的程式碼來講解一下關鍵的地方。 1.讓資訊UI跟隨著攝像機旋轉 想象一下我們需要實現的效果,當玩家站在水平面上時,敵人出現在四面八方,這時候我們通過轉動身體來尋找前後左右的敵人進行射擊。這個過程中,一些得分之類的UI資訊也同步顯示在玩家的視野中。 不過需要注意的是,當玩家進行擡頭和低頭的動作時,如果這些資訊UI也跟隨上下浮動,從遊戲設計上來說,沒有必要,因為我們不需要面對來自頭頂和地面的敵人,同時為了保證遊戲介面的穩定以防玩家不會輕易產生眩暈感,我們可以將這些UI元素的Y軸座標固定不動。 這樣這些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元素和攝像機的保持距離
在遊戲開始執行時,在Start方法中,儲存下攝像機和UI元素的距離,用來在遊戲時,UI元素旋轉時能和攝像機的距離保持不變。
 private void Start ()
  {
  m_DistanceFromCamera = Vector3.Distance (m_UIElement.position, m_Camera.position);
  }
下面是具體的實現方法:
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;
            }
        }
Vector3.ProjectOnPlane  將向量投影到由以另一個向量為法線定義的平面上 2.讓武器跟隨者玩家的視野改變朝向
我們要實現的效果如上圖所示,武器要隨著攝像機的朝向改變自己的朝向,下面是實現這個行為的具體程式碼:  //這個指令碼應該與射擊的武器的父級進行關聯 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場景。