這邊用個還算簡單的方法來達到這麼目標,也就是用兩個Camera來照各自的物件即可,遊戲的Camera照場景Culling Mask排除UI物件,而UI Camera則只有照UI物件,排除其他物件。
就如同畫面顯示的,這個UI有一塊黑色背景遮住場景,然後有一個面板顯示按鈕等等東西。
從編輯器的另一個角度來看,就可以看到場景的方塊其實是在最前面,黑色面板跟按鈕面板都在後面,但是UI卻不會被場景物件擋住,就是因為Camera的Depth不同。
首先需要匯入幾個免費的Plugin
SteamVR Plugin (https://www.assetstore.unity3d.com/en/#!/content/32647)
Vive Input Utility (https://www.assetstore.unity3d.com/en/#!/content/64219)
VRTK (https://www.assetstore.unity3d.com/en/#!/content/64131)
一開始先把SteamVR裡面的CameraRig拉到場景中,這時候額外建立一個Camera給UI使用,Culling Mask只選擇UI,然後Depth設定為0在眼睛Camera前面。
眼睛的Camera設定Culling Mask去掉UI,Depth預設值應該是-1不需要改,不過還是看自己的需求去設定Depth。
接著在Controller上面加上VRTK這個Plugin的Controller Event這個Component來取得控制器的事件。
VivePointer在Vive Input Utility這個Plugin的Demo裡面可以找到,直接複製過來就好。
接著做兩個簡單的UI面板,第一個是黑色背景,Render Mode選擇Screen Space - Camera,然後Camera就把剛剛的UI Camera拉進來設定就好。
然後第二個UI Canvas來顯示按鈕或什麼3D面板之類的,Render Mode選擇World,同樣Event Camera選擇UI Camera,然後這個Order in Layer設定為1,因為前面那個黑色背景的Order in Layer是0,避免被黑色背景擋住所以這邊往前移動。
這邊加了一個Canvas Raycast Target的Component來讓VR控制器去做碰撞。
接下來做一個簡易的開啟Menu選單,的Component
public class Test: MonoBehaviour { public GameObject[] ui; //所有UI面板 private bool toggle = false; void Start() { //使用VRTK的Plugin並且using VRTK;這個Namespace if (GetComponent<VRTK_ControllerEvents>() == null) { this.enabled = false; return; } GetComponent<VRTK_ControllerEvents> ().ApplicationMenuPressed += new ControllerInteractionEventHandler(DoApplicationMenuPressed); GetComponent<VRTK_ControllerEvents> ().ApplicationMenuReleased += new ControllerInteractionEventHandler(DoApplicationMenuReleased); } void Update() { } private void DoApplicationMenuPressed(object sender, ControllerInteractionEventArgs e) { } //當按下放開Vive的Pad前方的Nemu按鈕 private void DoApplicationMenuReleased(object sender, ControllerInteractionEventArgs e) { ToggleUI(!toggle); } public void ToggleUI(bool active) { foreach (GameObject go in ui) go.SetActive(active); toggle = active; } }
接著把這個Component隨便放到一個Controller上面,上面要有VRTK的Controller Events這個Component,然後把UI物件拉進去就完成了。
測試後按下Menu按鈕打開UI,會發現控制器怎麼會被遮住了,因為剛剛控制器物件沒有設定Layer。
這時候把控制器的Layer設定為UI,然後再測試一次看看。
這次控制器的顯示就正常了,就不會被擋住了。但是有沒有發現一件事情,場景中的方塊竟然還是可以被RayCast判斷到(黃色球球)
這邊可以打開VivePointers看裡面的EventRaycaster這個物件,看到這個Physic Raycast Method這個Component,可以在這邊做調整。
這邊就不詳細說明怎麼調整了,可以比較偷懶一點就是當按下Menu打開選單的時候,這邊的Mask Exclusive排除的部分加入場景的Layer,例如Default,這樣打開Menu選單後,Raycast就不會對場景物件做判斷。
然後關閉Menu的時候再把排除的Layer去掉Default,這時候又會對場景物件有Raycast的判斷了。
到這邊就告一段落了,如果有任何問題或錯誤歡迎提出。
No comments:
Post a Comment