【轉載】Unity3D VR 教程:3.VR中的交互

原文地址:http://blog.csdn.net/sherlockchang/article/details/51336901html

概述web

VR開發中,咱們常常須要激活一個用戶正在盯着的物體。咱們準備了一個示例,一個簡單的可擴展的輕量級的系統,讓用戶和物體交互。這個系統由三個主要的腳本組成,VREyeRaycaster, VRInput, 和VRInteractiveItem - 下面有一些簡短的說明和項目的源碼。app

 

VREyeRaycaster編輯器

這個腳本須要放在主攝像機上,每一次調用腳本的Update()向前發射一條射線, 調用Physics.Raycast來檢測是否是擊中了任何碰撞盒。這個功能能夠設置爲排除特定的layer(層),根據場景,可能須要把全部互動的物體移動到另外一個層來作顯示效果。ide

 

若是碰撞盒被射線集中,這個腳本會嘗試在目標對象上查找VRInteractiveItem 控件:oop

 

[csharp]  view plain copy
  1. VRInteractiveItem interactible = hit.collider.GetComponent<VRInteractiveItem>();    //attempt to get the VRInteractiveItem on the hit object  


經過這個咱們能夠知道用戶是否正在看着某個物體,或者中止查看某個物體,若是用戶開始查看或者中止查看某個物體,咱們能夠作一些響應,例如調用某個方法。佈局

 

 

VRInput測試

VRinput是個簡單的類,它用來兼容動做發生的來源,是使用GearVR上觸發的 swipes, taps, double-taps事件,仍是使用DK2時,專爲PC準備的輸入事件。動畫

 

能夠在VRInput 中直接註冊事件監聽:this

 

[csharp]  view plain copy
  1. public event Action<SwipeDirection> OnSwipe;                // Called every frame passing in the swipe, including if there is no swipe.  
  2. public event Action OnClick;                                // Called when Fire1 is released and it's not a double click.  
  3. public event Action OnDown;                                 // Called when Fire1 is pressed.  
  4. public event Action OnUp;                                   // Called when Fire1 is released.  
  5. public event Action OnDoubleClick;                          // Called when a double click is detected.  
  6. public event Action OnCancel;                               // Called when Cancel is pressed.  

 

 

關於註冊事件監聽的更多信息,請查看咱們的事件教程

 

VRInteractiveItem

任何想在VR中進行互動的物體均可以添加這個組件。須要物體上有碰撞盒。

 

這裏有6個能夠進行監聽的事件:

 

[csharp]  view plain copy
  1. public event Action OnOver;             // Called when the gaze moves over this object  
  2. public event Action OnOut;              // Called when the gaze leaves this object  
  3. public event Action OnClick;            // Called when click input is detected whilst the gaze is over this object.  
  4. public event Action OnDoubleClick;      // Called when double click input is detected whilst the gaze is over this object.  
  5. public event Action OnUp;               // Called when Fire1 is released whilst the gaze is over this object.  
  6. public event Action OnDown;             // Called when Fire1 is pressed whilst the gaze is over this object.  

 

 

添加一個boolean變量,用來查看如今是否是在Over( 懸停)的狀態:

 

[csharp]  view plain copy
  1. public bool IsOver  
  2. {  
  3.     get{ return m_IsOver; }              // Is the gaze currently over this object?}  

 

 

你能夠建立本身的腳原本響應這些事件,這裏有一個很是簡單的例子,用到了這裏的一些事件:

 

[csharp]  view plain copy
  1. using UnityEngine;  
  2. using VRStandardAssets.Utils;  
  3.   
  4. namespace VRStandardAssets.Examples  
  5. {  
  6.     // This script is a simple example of how an interactive item can  
  7.     // be used to change things on gameobjects by handling events.  
  8.     public class ExampleInteractiveItem : MonoBehaviour  
  9.     {  
  10.         [SerializeField] private Material m_NormalMaterial;                  
  11.         [SerializeField] private Material m_OverMaterial;                    
  12.         [SerializeField] private Material m_ClickedMaterial;                 
  13.         [SerializeField] private Material m_DoubleClickedMaterial;           
  14.         [SerializeField] private VRInteractiveItem m_InteractiveItem;  
  15.         [SerializeField] private Renderer m_Renderer;  
  16.   
  17.   
  18.         private void Awake ()  
  19.         {  
  20.             m_Renderer.material = m_NormalMaterial;  
  21.         }  
  22.   
  23.   
  24.         private void OnEnable()  
  25.         {  
  26.             m_InteractiveItem.OnOver += HandleOver;  
  27.             m_InteractiveItem.OnOut += HandleOut;  
  28.             m_InteractiveItem.OnClick += HandleClick;  
  29.             m_InteractiveItem.OnDoubleClick += HandleDoubleClick;  
  30.         }  
  31.   
  32.   
  33.         private void OnDisable()  
  34.         {  
  35.             m_InteractiveItem.OnOver -= HandleOver;  
  36.             m_InteractiveItem.OnOut -= HandleOut;  
  37.             m_InteractiveItem.OnClick -= HandleClick;  
  38.             m_InteractiveItem.OnDoubleClick -= HandleDoubleClick;  
  39.         }  
  40.   
  41.   
  42.         //Handle the Over event  
  43.         private void HandleOver()  
  44.         {  
  45.             Debug.Log("Show over state");  
  46.             m_Renderer.material = m_OverMaterial;  
  47.         }  
  48.   
  49.   
  50.         //Handle the Out event  
  51.         private void HandleOut()  
  52.         {  
  53.             Debug.Log("Show out state");  
  54.             m_Renderer.material = m_NormalMaterial;  
  55.         }  
  56.   
  57.   
  58.         //Handle the Click event  
  59.         private void HandleClick()  
  60.         {  
  61.             Debug.Log("Show click state");  
  62.             m_Renderer.material = m_ClickedMaterial;  
  63.         }  
  64.   
  65.   
  66.         //Handle the DoubleClick event  
  67.         private void HandleDoubleClick()  
  68.         {  
  69.             Debug.Log("Show double click");  
  70.             m_Renderer.material = m_DoubleClickedMaterial;  
  71.         }  
  72.     }  
  73. }  

 

 

要查看這個基礎的示例的話,能夠看一下VRSampleScenes/Scenes/Examples/ 中的InteractiveItem 場景

 

 

SelectionRadial(環形選擇區) 和 SelectionSlider(滑塊選擇區)

(用來確認選項)

咱們用了一個圓形選擇區,還有一個滑塊選擇區,玩家能夠按住Fire1 來確認交互動做:
 
按住輸入的按鍵, 選擇條會填滿, 而後發送OnSelectionComplete (選擇完成)或者 OnBarFilled(讀條失敗)事件。這部分代碼在SelectionRadial.cs和SelectionSlider.cs 文件中而且有詳細的註釋。對於VR來講,站在用戶體驗角度考慮,用戶知道他們在作什麼並且可以隨時把控整個各個方面。同時提供一個「held input (保持輸入)」的確認模式,做爲對當即響應事件的一些妥協。

 

VR示例場景中的一些互動示例

如今咱們來研究一下VR示例項目中的一些例子。咱們會討論一下每一個場景的互動效果和它們的實現方法。

 

在菜單場景中的互動

每一個菜單畫面都有幾個組件。特別須要瞭解一下的是MenuButton, VRInteractiveItem, 和Mesh Collider。

MenuButton 組件監聽了來自 VRInteractiveItem 組件的 OnOver 和 OnOut 事件, 當準星懸停在菜單畫面上的時候, 環形選擇塊就會出現, 當視線離開menu item(菜單選項)時, 這個環形選擇塊會消失。當選擇圈可見的時候,按下Fire1 鍵, 這個環形會逐漸填滿:

這個類也監聽了OnSelectionComplete 事件, 當環形圈填滿的時候,HandleSelectionComplete 方法會被調用,它會讓顯示器淡出而後讀取所選擇的關卡。

 

[csharp]  view plain copy
  1. private void OnEnable ()  
  2. {  
  3.     m_InteractiveItem.OnOver += HandleOver;  
  4.     m_InteractiveItem.OnOut += HandleOut;  
  5.     m_SelectionRadial.OnSelectionComplete += HandleSelectionComplete;  
  6. }  
  7.   
  8.   
  9. private void OnDisable ()  
  10. {  
  11.     m_InteractiveItem.OnOver -= HandleOver;  
  12.     m_InteractiveItem.OnOut -= HandleOut;  
  13.     m_SelectionRadial.OnSelectionComplete -= HandleSelectionComplete;  
  14. }  
  15.         
  16.   
  17. private void HandleOver()  
  18. {  
  19.     // When the user looks at the rendering of the scene, show the radial.  
  20.     m_SelectionRadial.Show();  
  21.   
  22.     m_GazeOver = true;  
  23. }  
  24.   
  25.   
  26. private void HandleOut()  
  27. {  
  28.     // When the user looks away from the rendering of the scene, hide the radial.  
  29.     m_SelectionRadial.Hide();  
  30.   
  31.     m_GazeOver = false;  
  32. }  
  33.   
  34.   
  35. private void HandleSelectionComplete()  
  36. {  
  37.     // If the user is looking at the rendering of the scene when the radial's selection finishes, activate the button.  
  38.     if(m_GazeOver)  
  39.         StartCoroutine (ActivateButton());  
  40. }  
  41.   
  42.   
  43. private IEnumerator ActivateButton()  
  44. {  
  45.     // If the camera is already fading, ignore.  
  46.     if (m_CameraFade.IsFading)  
  47.         yield break;  
  48.   
  49.     // If anything is subscribed to the OnButtonSelected event, call it.  
  50.     if (OnButtonSelected != null)  
  51.         OnButtonSelected(this);  
  52.   
  53.     // Wait for the camera to fade out.  
  54.     yield return StartCoroutine(m_CameraFade.BeginFadeOut(true));  
  55.   
  56.     // Load the level.  
  57.     SceneManager.LoadScene(m_SceneToLoad, LoadSceneMode.Single);  
  58. }  



 

這裏有一些關於Selection Radial的示例, 注意截圖中央的粉色圖形。

只有點狀準星的:

 

空的選擇確認圈, 由於如今正在看着menu 場景因此出現:

 

選擇確認圈正在填充(用戶正在看着菜單畫面, 並且按住了 輸入設備的 Fire1 鍵):

經過在研究示例項目中的進度條和環形試,着掌握這個模式。咱們建議你在本身的VR項目上考慮一下這個方法,這樣能保證用戶體驗的一致性,也能幫助他們適應這個新的設備。

 

Maze Scene 中的交互

迷宮遊戲提供了一個桌遊模式的交互,在這裏你須要用開關(擋板)來引導角色必考炮塔,到達終點。

 

爲角色選擇目的地的時候,會出現一個目的地標記,路上會出現一條路線,讓角色沿着軌跡前進。在觸控板上滑動,或者按下方向鍵,或者用手柄左搖桿,能夠旋轉畫面。

 

MazeFloor 對象 有一個MeshCollider 組件和一個VRInteractiveItem 組件, 讓它能在VR中進行交互:

MazeCourse 物體 包含有MazeFloor 和MazeWalls ,包含着用做迷宮佈局的幾何體:

 

MazeCourse 物體添加了MazeTargetSetting腳本, 有一個VRInteractiveItem 的引用,指向MazeFloor物體上的VRInteractiveItem 組件:

 

MazeTargetSetting 監聽了來自VRInteractiveItem 的 OnDoubleClick 事件, 而後它會發送OnTargetSet 事件。這個事件會把準星的Transform(空間座標信息)看成變量一塊兒傳出:

 

[csharp]  view plain copy
  1. public event Action<Transform> OnTargetSet;                     // This is triggered when a destination is set.  
  2.   
  3.      
  4. private void OnEnable()  
  5. {  
  6.     m_InteractiveItem.OnDoubleClick += HandleDoubleClick;  
  7. }  
  8.   
  9.   
  10. private void OnDisable()  
  11. {  
  12.     m_InteractiveItem.OnDoubleClick -= HandleDoubleClick;  
  13. }  
  14.   
  15.   
  16. private void HandleDoubleClick()  
  17. {  
  18.     // If target setting is active and there are subscribers to OnTargetSet, call it.  
  19.     if (m_Active && OnTargetSet != null)  
  20.         OnTargetSet (m_Reticle.ReticleTransform);  
  21. }  

 

 

MazeCharacter 物體上的 Player 組件和 MazeDestinationMarkerGUI 物體上的 DestinationMarker 組件都監聽了OnTargetSet這個事件,而後相應的作出了反應。

 

角色使用了Nav Mesh systems(導航系統)在迷宮中尋路。Player 組件實現了HandleSetTarget方法,在方法中,把導航系統的目標點設置爲準星的座標, 而後更新它對玩家軌跡的渲染:

 

[csharp]  view plain copy
  1. private void HandleSetTarget(Transform target)  
  2. {  
  3.     // If the game isn't over set the destination of the AI controlling the character and the trail showing its path.  
  4.     if (m_IsGameOver)  
  5.         return;  
  6.               
  7.     m_AiCharacter.SetTarget(target.position);  
  8.     m_AgentTrail.SetDestination();  
  9. }  

 

 

DestinationMarker (目標點生成器)會把標記移動到準星Transform的位置:

 

[csharp]  view plain copy
  1. private void HandleTargetSet(Transform target)  
  2. {  
  3.     // When the target is set show the marker.  
  4.     Show();  
  5.   
  6.     // Set the marker's position to the target position.  
  7.     transform.position = target.position;  
  8.   
  9.     // Play the audio.  
  10.     m_MarkerMoveAudio.Play();  
  11.   
  12.     // Play the animation on whichever layer it is on, with no time offset.  
  13.     m_Animator.Play(m_HashMazeNavMarkerAnimState, -1, 0.0f);  
  14. }  

 

 

你能夠看到準星,目的地製做器,玩家,和軌跡:

 

迷宮中的開關也是一個在VR中和物體互動的例子。使用了一個Collider(碰撞盒),像VRInteractiveItem 和SelectionSlider 這兩個類同樣。

像以上演示的和其餘物體的互動, SelectionSlider腳本監聽了 VRInteractiveItem 和 VRInput 發出的事件:

 

[csharp]  view plain copy
  1. private void OnEnable ()  
  2. {  
  3.     m_VRInput.OnDown += HandleDown;  
  4.     m_VRInput.OnUp += HandleUp;  
  5.   
  6.     m_InteractiveItem.OnOver += HandleOver;  
  7.     m_InteractiveItem.OnOut += HandleOut;  
  8. }  



 

Flayer 場景中的交互

飛行器場景是一個無限飛行的遊戲,玩家須要控制飛船在場景中飛行,使用Fire1 進行射擊, 射擊小行星,穿過空中的門,都能增長分數。玩法相似飛行俱樂部和星際火狐。

 

在交互方面,Flyer是一個更簡單的案例, FlyerLaserController 監聽了 VRInput 的O nDown 事件來發射激光:

 

[csharp]  view plain copy
  1. private void OnEnable()  
  2. {  
  3.     m_VRInput.OnDown += HandleDown;  
  4. }  
  5.   
  6.   
  7. private void HandleDown()  
  8. {  
  9.     // If the game isn't running return.  
  10.     if (!m_GameController.IsGameRunning)  
  11.         return;  
  12.   
  13.     // Fire laser from each position.  
  14.     SpawnLaser(m_LaserSpawnPosLeft);  
  15.     SpawnLaser(m_LaserSpawnPosRight);  
  16. }  



 

 

Shooter180 和 Shooter360 場景中的交互(Target Gallery/Target Arena)

 

VR示例實現了兩個射擊遊戲,180度走廊打靶射擊遊戲,和360度的競技場射擊遊戲。

 

每一個在射擊遊戲裏建立的靶子都有 Collider, VRInteractiveItem 和 ShootingTarget 組件。

ShootingTarget 組件監聽了VRInteractiveItem發出的OnDown事件,來判斷標靶是否是被射擊。這個方法適合即時射擊,若是要作一個擊中數的模式,咱們須要另外一個方案實現。

 

如今你可能對 VR交互組件 有了一個大概認識,知道了這些組件是如何在VR 示例項目中使用的。如今咱們來討論一下注視和準星是如何在咱們的VR示例中生效的。

 

注視

在VR中偵測玩家正在查看的方向是很重要的,關係到是否容許用戶和物體互動,激活動畫,或者對對目標發射子彈等等。咱們引用的這個動做,在VR中叫作「gaze」(注視), 並且,接下來咱們會在咱們的VR文章中,使用這個術語。

 

因爲大多數頭戴式顯示設備還不支持眼球追蹤,咱們如今只能估算玩家的注視。由於鏡片的扭曲,這意味着玩家基本上是朝前看的,因此有一個簡單的解決方案。就像在概述中提到的,咱們只須要在攝像機中心朝前發射一條射線,而後查找這條射線全部碰撞的物體。固然,這意味着任何物體能被碰撞(或者經過注視進行互動)的物體都要有碰撞盒。

 

準星

準星能夠幫助指示出玩家的視野中心。準星能夠是一個簡單的點,或者是個交叉十字線,這要看項目的需求。

 

在傳統的3D遊戲中,準星一般被設置爲空間中固定的點, 一般是屏幕的中心。 在VR中定位一個準星要更復雜:用戶在VR場景中觀察環境,視線會彙集到離攝像機比較近的物體上。若是準星有一個固定的位置, 用戶會看到兩個:能夠把手指放在眼前而後看遠處的物體來模擬一下這個感受, 若是你聚焦到你的手指,背景的物體看起來會變成兩個, 反之一樣。這被叫作voluntary Diplopia(自發性複視)。

 

要避免用戶觀察環境時和注視不一樣距離的物體時看到兩個準星,須要把準星放到物體表面正在被觀察的點,而後根據攝像機到這個點的距離對它進行縮放。

 

有一些簡單的例子來演示準星如何處理不一樣距離和尺寸, 來自 Examples/Reticlescene (示例/準星場景)

準星被放置在一個物體上,靠近攝像機:

準星被放置在一個遠處的物體上:

準星放置在遠處的位置:

因爲調整了位置和縮放, 準星在用戶看來是同樣的大小,也忽略的它到攝像機的距離。

 

當注視的射線上沒有物體的時候,咱們簡單的把準星放到一個預設的距離上。在一個護腕環境,這個被簡單的放在攝像機的最遠端裁剪面上,或者在室內場景的話,這個位置會變得更近。

 

越過其餘物體渲染準星

 

若是準星被放置在了和物體一樣的位置, 這個準星可能和其餘附近的物體有重疊:

要解決這個問題,咱們須要保證準星渲染在全部其餘物體之上。VR示例中提供了一個基於 「UI/Unlit/Text」的shader,叫作UIOverlay.shader。給材質選擇shader的時候,能夠在「UI/Overlay」下面找到它。

 

這個shader能夠用在UI元素和文字,會在其它物體的最上方渲染:

調整準星到場景中的其餘物體

 

最後,若是須要旋轉準星來貼合到視線擊中的物體上。咱們能夠用RaycastHit.normal。這裏演示如何在準星中設置:

 

 

[csharp]  view plain copy
  1. public void SetPosition (RaycastHit hit)  
  2. {  
  3.     m_ReticleTransform.position = hit.point;  
  4.     m_ReticleTransform.localScale = m_OriginalScale * hit.distance;  
  5.   
  6.     // If the reticle should use the normal of what has been hit...  
  7.     if (m_UseNormal)  
  8.         // ... set it's rotation based on it's forward vector facing along the normal.  
  9.         m_ReticleTransform.rotation = Quaternion.FromToRotation (Vector3.forward, hit.normal);  
  10.     else  
  11.         // However if it isn't using the normal then it's local rotation should be as it was originally.  
  12.         m_ReticleTransform.localRotation = m_OriginalRotation;  
  13. }  



 

能夠在迷宮場景中看到這個動做。

下面是準星如何貼合到牆壁上:



準星貼合到地面:

咱們已經引入了一個示例準星腳本。 和 VREyeRaycaster 一塊兒把準星定位到場景中,有選項控制是否貼合到目標物體表面。

以上全部都能在VRSampleScenes/Scenes/Examples/ 文件夾下的 Reticle scene 查看。

 

VR中頭部的旋轉和座標

 

HMD(頭戴式顯示設備)旋轉和座標的明顯的用途是用來觀察環境,可是這兩個變量,用來和環境互動也是能夠的。

 

須要使用 VR.InputTracking class 這個類來獲得這兩個值,而後區分須要進入哪一個 VRNode(VR節點)。咱們須要使用VRNode.Head來獲得頭部的旋轉。頭部,而不是每隻眼睛。關於這個的更多信息,能夠參考Getting Started with VR Development這篇文章。

 

把旋轉做爲一種輸入類型的示例,基於頭部旋轉來精確的旋轉一個菜單或者其餘物體。能夠在這裏找到這裏示例,VRSampleScenes/Examples/Rotation scene, 如下示例腳本:

 

[csharp]  view plain copy
  1. // Store the Euler rotation of the gameobject.  
  2. var eulerRotation = transform.rotation.eulerAngles;  
  3.   
  4. // Set the rotation to be the same as the user's in the y axis.  
  5. eulerRotation.x = 0;  
  6. eulerRotation.z = 0;  
  7. eulerRotation.y = InputTracking.GetLocalRotation(VRNode.Head).eulerAngles.y;  



 

能夠看到物體會根據玩家查看的方向進行旋轉:

在咱們的示例Flyer game(飛行器遊戲)中,你能夠看到FlyerMovementController中,基於頭部的旋轉調整飛船座標:

 

[csharp]  view plain copy
  1. Quaternion headRotation = InputTracking.GetLocalRotation (VRNode.Head);  
  2. m_TargetMarker.position = m_Camera.position + (headRotation * Vector3.forward) * m_DistanceFromCamera;  


 

 

VR 遊戲中 與觸控板和鍵盤的交互

 

Gear VR 在設備側面有觸控板。對於Unity來講,表現爲出鏢, 能夠經過下面的方式調用:

 

Input.mousePosition

Input.GetMouseButtonDown

Input.GetMouseButtonUp

使用Gear VR時,可能也許須要獲取觸控板的滑動數據。咱們引入了一個VRInput 腳原本處理滑動,觸屏點擊,和觸屏雙擊。也接受鍵盤輸入中的方向鍵和左Ctrl鍵(Unity默認輸入術語中的Fire1),來觸發swipes(滑動)和taps(點擊)。

 

在Unity編輯器中,因爲如今沒有辦法測試Unity到GearVR的內容,可能用DK2來測試GearVR 的內容。因爲Gear VR 觸控板事件是做爲鼠標事件運做的,咱們能夠簡單的使用鼠標來模擬輸入。因爲使用HMD(頭戴式顯示設備)時,定位鍵盤要更簡單一點, 爲了方便,VRInput也會接受方向鍵做爲滑動事件,而後左Ctrl(Fire1)做爲觸屏點擊事件(taps)。

 

對於手柄的基礎操做,左搖桿的動做會做爲華東,而後按下其中一個按鈕會做爲點擊。

 

在VRSampleScenes/Scenes/Examples/Touchpad中有一個例子監聽了swipes(滑動)事件。

 

一下是ExampleTouchpad 腳本, 按照滑動的方向,對剛體添加扭力,讓物體可以旋轉起來。

 

[csharp]  view plain copy
  1. using UnityEngine;  
  2. using VRStandardAssets.Utils;  
  3.   
  4. namespace VRStandardAssets.Examples  
  5. {  
  6.     // This script shows a simple example of how  
  7.     // swipe controls can be handled.  
  8.     public class ExampleTouchpad : MonoBehaviour  
  9.     {  
  10.         [SerializeField] private float m_Torque = 10f;  
  11.         [SerializeField] private VRInput m_VRInput;                                          
  12.         [SerializeField] private Rigidbody m_Rigidbody;                                      
  13.   
  14.   
  15.         private void OnEnable()  
  16.         {  
  17.             m_VRInput.OnSwipe += HandleSwipe;  
  18.         }  
  19.   
  20.   
  21.         private void OnDisable()  
  22.         {  
  23.             m_VRInput.OnSwipe -= HandleSwipe;  
  24.         }  
  25.   
  26.   
  27.         //Handle the swipe events by applying AddTorque to the Ridigbody  
  28.         private void HandleSwipe(VRInput.SwipeDirection swipeDirection)  
  29.         {  
  30.             switch (swipeDirection)  
  31.             {  
  32.                 case VRInput.SwipeDirection.NONE:  
  33.                     break;  
  34.                 case VRInput.SwipeDirection.UP:  
  35.                     m_Rigidbody.AddTorque(Vector3.right * m_Torque);  
  36.                     break;  
  37.                 case VRInput.SwipeDirection.DOWN:  
  38.                     m_Rigidbody.AddTorque(-Vector3.right * m_Torque);  
  39.                     break;  
  40.                 case VRInput.SwipeDirection.LEFT:  
  41.                     m_Rigidbody.AddTorque(Vector3.up * m_Torque);  
  42.                     break;  
  43.                 case VRInput.SwipeDirection.RIGHT:  
  44.                     m_Rigidbody.AddTorque(-Vector3.up * m_Torque);  
  45.                     break;  
  46.             }  
  47.         }  
  48.     }  
  49. }  



 

VR示例中的VRInput例子

像上文提到的,全部咱們的示例遊戲,都用VRInput來處理觸控板和鼠標事件。在Maze(迷宮)中的攝像機也響應了滑動事件。

 

Maze(迷宮)

在這個場景中,攝像機軌道監聽了swipes(滑動)事件,可以改變視角:

 

[csharp]  view plain copy
  1. private void OnEnable ()  
  2. {  
  3.     m_VrInput.OnSwipe += HandleSwipe;  
  4. }  
  5.   
  6.   
  7. private void HandleSwipe(VRInput.SwipeDirection swipeDirection)  
  8. {  
  9.     // If the game isn't playing or the camera is fading, return and don't handle the swipe.  
  10.     if (!m_MazeGameController.Playing)  
  11.         return;  
  12.   
  13.     if (m_CameraFade.IsFading)  
  14.         return;  
  15.   
  16.     // Otherwise start rotating the camera with either a positive or negative increment.  
  17.     switch (swipeDirection)  
  18.     {  
  19.         case VRInput.SwipeDirection.LEFT:  
  20.             StartCoroutine(RotateCamera(m_RotationIncrement));  
  21.             break;  
  22.   
  23.         case VRInput.SwipeDirection.RIGHT:  
  24.             StartCoroutine(RotateCamera(-m_RotationIncrement));  
  25.             break;  
  26.     }  
  27. }  


關於爲何場景的攝像機軌道而不是直接旋轉這個迷宮自己,請查看 Movement article 這篇文章。

 

如今你對VR 示例場景中,基礎VR交互的工做原理有了一個更好的認識。有不少方法去完成這個事情,可是這個方法學起來又快又簡單。在下一篇文章裏,咱們會討論VR中不一樣類型的用戶界面。同時記得,打算向一樣研究VR的朋友們提問關於VR的問題的話,你能夠跳轉到Unity官方論壇VR板塊

 

 

 

在迷宮場景中看到這個動做。

 

下面是準星如何貼合到牆壁上:

相關文章
相關標籤/搜索