來源:映維網
在今年8月,映維網分享了Fanbank首席技術官斯科特·蓋耶(Scott Geye)是如何用Quest和Unity等工具制作一個炫酷的混合現實公寓。現在,蓋耶又通過后續博文介紹了在所述基礎上進一步優化混合現實公寓的一系列方式。
延伸閱讀:如何用Oculus Quest將自己公寓打造成MR科幻游樂場
下面是映維網的具體整理:
如何用按鈕來為你的公寓實現交互性
在上一篇教程中,我介紹了如何用Oculus Quest和Unity打造一個混合現實公寓的所有步驟。在這個基礎之上,我們可以進一步探索強化虛擬公寓的有趣方式。
在我成長的過程中,我喜歡諸如《Cosmic Osmo》和《神秘島》這樣的游戲(以及最近的《The Room》)。所述游戲要求你探索一個虛擬世界,并通過與環境交互來發現隱藏的線索。當我在思考如何通過各種有趣功能來進一步裝飾我的公寓時,先行隱藏相關控件,并在執行特定操作時顯露成為了自然而然的下一步。我想看看自己是否能重現當在房間里發現不存在于現實世界中的元素時的興奮感覺。
我決定把我的咖啡桌作為主控制中心,但在收到請求之前,我會先把實際的控件隱藏在桌子里面。一旦控件顯露,這將提供允許我與整個房間進行交互的方式。我想看看在屋頂開一個大洞會是什么樣子,因為這樣我就想能夠動態地調整公寓內外的環境。我同時想看看擺設一臺大電視的感覺。200寸的屏幕可能有點夸張,但超級酷。
在下面這個教程中,我將向你介紹我為房間增加交互性的技術。希望本文能夠為你提供啟發鼓勵,并幫助你天馬行空地打造屬于自己的科幻未來公寓。
在開始之前,我們需要一定的代碼操作,但我編寫的腳本可以直接放到你的項目中。當然,如果你希望進一步擴展,我的代碼編輯起來應該足夠簡單。
1. 制作一個隱藏的隔間
在打造和裝飾我的數字公寓之后,一個主要的挑戰是如何創造一個藏匿控件的地方。我最初并沒有設計任何包含隔間或活板門的元素,我所有的家具都來自于預先建造的asset。最簡單的方法是使用ProBuilder并在任何需要的地方打一個洞。
ProBuilder有一個實驗性的Boolean工具,它允許你將兩個ProBuilder對象合并,或從另一個對象中減去一個的體積。根據我的經驗,這個工具完全符合我的預期,所以不要被實驗這個詞嚇倒。如果嘗試使用更復雜的形狀,你肯定會遇到一些小麻煩。所述工具必須從一組三角形中重新創建每個面,所以對于原本可能是每邊有兩個三角形的立方體,如果你減去圓形,情況就會變得非常復雜,會出現大量的新三角形。這確實有可能導致渲染問題,但這個工具應該不會破壞原始對象,所以你可以嘗試一下,看看它的處理效果如何。
你需要在ProBuilder下的Unity Preferences中打開實驗功能,然后從ProBuilder/Experimental/Boolean(CSG)Tool下的Tools菜單打開Boolean Tool。
我首先是在咖啡桌上開一個洞并用來放置控制面板。我為桌子使用的預制件被分割成用于桌面和桌腿的對象,但如果你需要,你應該非常容易從零開始創建一個類似的桌子。
要使用Boolean Tool,兩個對象都必須是ProBuilder對象,所以你可以使用ProBuilder創建一個新的多維數據集,并使其與原始桌面大小相同,然后關閉原始桌面。接下來,創建一個ProBuilder立方體,將其用作從新桌面(即孔)減去的體積。將它們正確地放在彼此上方,打開Boolean Tool,將新的桌面從對象Hierarchy拖到第一個槽中,然后將減法立方體拖到第二個槽中。將你的Operation選為Subtraction并點擊Apply。
這樣你就留下三個對象:原始的兩個對象和一個新對象,后者是減法運算的結果。這三者在制作動畫時非常有用,所以要相應地重命名它們,暫時隱藏兩個原始對象,這樣你就可以看到減法的效果了。
2. 設置桌子
現在我們的桌子有了一個用于隱藏隔間的洞,而我們同時需要創建隔間的內部、控制面板本身、以及用于顯露面板的門。我們將使用Unity的動畫工具來確保所有一切協調地移動。
要創建隱藏分區的內部,請找到用于執行布爾減法的立方體。選擇頂面,然后稍微插入表面,形成我們隔間的邊緣。
接下來,朝立方體底部向下擠出插入面。你應該留下一個看起來像空盒子的元素。把你的立方體放在桌面的洞里,使立方體的頂部略低于桌面。
下一步,創建一個新的立方體來作為我們的控制面板,將其移動到隱藏的隔間內并調整大小。
然后,創建另一個立方體用作可伸縮門。把它移到適當的地方,確保它的大小能蓋住這個洞,并且與桌面齊平。確定寬度的測量值,除以這個數的一半,然后以這個寬度設置立方體。接下來,復制立方體,這樣你就有了兩個門。相應地定位第二個門。
3. 設置控制面板的動畫
為了一次過設置所有桌面對象的動畫,我們需要將它們全部移動到Hierarchy的同一父對象下面。轉到Game Object菜單,選擇Create Empty,將其重命名為Control Panel,然后將所有桌面對象拖動到所述對象之下。
為了簡單起見,我們將使用Unity的內置動畫工具。通過選擇Window/Animation/Animation菜單來打開Animation視圖。選擇我們的Control Panel父對象,然后在Animation視圖中單擊Create以創建一個新的動畫片段,并將其命名為ControlPanelAnim。
在視圖中打開新片段后,單擊紅色錄制圖標并將時間軸移到1:00(1秒)標記位置。現在,選擇每一個伸縮門,將它們縮小到零單位寬,并將它們與孔的最近邊對齊。關閉錄制并點擊播放。門應該從中間打開并顯露你的面板。
返回到1:00標記,然后單擊Animation視圖中的Add Property按鈕。打開Panel/Transform并單擊Rotation旁邊的加號(+)按鈕。通過同樣的過程來添加Position。然后單擊動畫控件第二行的Add Keyframe按鈕。這將鎖定面板的旋轉和位置,直到所述時間點,這樣它就不會從0:00移動到1:00。接下來,將時間軸移到2:00,單擊錄制并將面板旋轉45度,然后調整其位置,使其面向與房間中面板交互的任何位置。再次關閉錄制并點擊播放,從而確保你的面板被伸縮門正確顯示并旋轉到位。
如果運行整個場景,你會注意到動畫立即播放。因為我們希望動畫被觸發,所以我們需要在Animator窗口中進行一定調整。選擇ControlPanel對象并打開Animator窗口。你將看到一個連接到ControlPanelAnim狀態的Entry狀態。右鍵單擊它并創建一個新的Empty狀態,然后將其命名為IdleStart。右鍵單擊Entry狀態并選擇setstatemachine Default State,然后將轉換線拖到IdleStart狀態。現在,當你開始場景時,動畫在被觸發之前講不會播放,因為它永遠不會轉換到ControlPanelAnim狀態。
4. 按鈕
我想通過一個簡單的按鈕機制來觸發房間里的所有動畫。如果你想深入UI,Mixed Reality Tool Kit(MRTK)是一個很好的資源。但這一次我們將使用Oculus Sample Framework中的預置和腳本。
如果沒有試過,我建議你嘗試一下Model Train Hand Tracking場景(Assets/Oculus/SampleFramework/Usage/handsinteractiontrainsect)。
這實際上相當有趣。
要在場景中使用相同的按鈕,需要添加以下三個預制件:
Assets/Oculus/SampleFramework/Core/HandsInteraction/Prefabs/InteractableToolsSDKDriverAssets/Oculus/SampleFramework/Core/HandsInteraction/Prefabs/HandsManagerAssets/Oculus/SampleFramework/Usage/HandsTrainExample/Prefabs/NearFieldButton.prefab
把NearFieldButton放在場景中的合適地方(我選擇了桌子的邊緣)。下一步,我們需要配置所有一切以適配場景。
單擊HandsManager對象并在Inspector中查看HandManger腳本。返回到Hierarchy,打開OVRCameraRig對象,直到你發現Right和LeftHandAnchors。將每只手對應的OvrHandPrefabs拖到HandsManger Inspector中相應的字段中。
另外,對于每個OvrHandPrefab,你需要確保在Inspector中啟用了Enable Physics Capsules。這將在每個食指的尖端添加一個球體,并允許系統捕捉與手指和按鈕的交互。
現在我們已經設置了按鈕交互,下面我們來構建和運行項目,從而確保手部追蹤工作正常。當你觸碰按鈕時,它應該會亮起,而你會聽到一聲咔嗒聲。
5. 觸發動畫
現在我們已經完成了按鈕和動畫,下面我們將兩者結合起來。這是我們的第一個腳本。首先,我們需要創建一個空對象來應用腳本。創建一個新的空對象并將其稱為PanelController。接下來,為PanelController打開Inspector,單擊addcomponent,然后單擊NewScript并調用文件PanelController。下面是我們用于觸發第一個動畫的初始代碼:
你應該能夠在任何文本編輯器中打開腳本,復制/粘貼上面的內容,保存文件并將其自動導入Unity。如果你再次為Panel Controller對象查看Inspector,你將在Panel Controller(Script)部分看到一個空的Panel字段。將ControlPanel父對象拖動到所述字段,以便我們在腳本中使用它。
我已經將腳本設置成你可以直接在編輯器中運行項目,并通過在Game窗口中點擊P鍵來測試動畫。當場景運行時,動畫應該會不斷循環。要關閉循環,請停止項目,在資源中找到ControlPanelAnim文件,單擊文件并查看Inspector,然后取消選中Loop Time。
現在,如果嘗試重新運行并按P鍵,動畫將只運行一次。
要將動畫鏈接到按鈕,我們需要告訴按鈕從腳本調用RunControlPanelAnimation函數。單擊NearFieldButton并導航到ButtonController(Script)。單擊InteractionableStateChanged列表下的加號(+)按鈕,并將PanelController對象拖動到None(object)字段。現在你可以選擇PanelController/RunControlPanelAnimation。
現在,你可以在頭顯中構建并運行項目。單擊按鈕后你會看到動畫開始。
6. 重新隱藏面板
面板打開后,我希望能夠再次單擊按鈕以關閉面板,甚至可以單擊動畫中間的按鈕來再次關閉/打開面板(加分項)。我們不需要創建單獨的動畫來隱藏面板,我們只需反向運行相同的動畫,并使用Animator窗口、Animation States和腳本更新。
我們的計劃是將一個動畫狀態用于打開面板,一個用于關閉面板,一個狀態用于動畫開始前的待機時間,另一個用于動畫結束后的待機時間。這樣,我們就可以從腳本中測試動Animaor的狀態,并進行適當的轉換。
在Animator窗口中,單擊ControlPanelAnim狀態并將其重命名為AnimForward。復制(復制/粘貼)狀態并將其命名為AnimBackward。選擇AnimBackward并在Inspector中將Speed值更改為-1,這樣動畫在所述狀態下將向后運行。
選擇IdleStart狀態,將Speed設置為零,然后將ControlPanelAnim從Assets拖動到空的Motion字段中。復制IdleStart狀態并將復制重命名為IdleEnd。添加動畫以確保片段的第一幀和最后一幀將在所述狀態下播放。
下一步,通過右鍵單擊每個狀態并選擇Make Transtion來創建三個新的變換:
IdleState to AnimForwardAnimBackward to IdleStateAnimForward to IdleEnd
現在,單擊AnimForward to IdleEnd轉換,打開Inspector中的Settings并將Transition Offset設置為1。當處于IndleEnd狀態時,這將強制動畫在最后一幀待機。
所有這一切的結果是,如果AnimForward播放到最后,IdleEnd將開始并停留在最后一幀。如果AnimBackward播放到最后,IdleStart將開始并停留在第一幀。
最后,我們只需要更新腳本來處理這些新狀態。
我所做的只是更新我們的processAnimation函數,從而處理我們可能發現的所有四種狀態:
IdleState:向前播放動畫IdleEnd:向后播放動畫AnimForward:我們正在向前播放動畫,所以我們需要切換到在動畫時間軸的同一位置向后播放動畫。AnimBackward:與Animforward相同,但我們是在向后播放,所以我們需要切換到向前播放動畫。
我們只能檢索每個正在播放的狀態的時間。這是一個介于0和1之間的值,它表示我們在動畫中的距離,不考慮片段的長度(例如百分比)。當在狀態之間切換時,我們需要同時播放反向片段,但要從時間軸的另一端開始播放。這需要我們計算當前播放片段的標準化時間的倒數,并將值作為新的開始位置,然后傳遞給另一個狀態的播放函數。
有了腳本設置,我們可以在動畫的任何階段點擊按鈕以令它前進或后退,并在開始和結束時暫停。
7. 改變環境
現在我們有了控制面板,我們只需為控制面板添加額外的近場按鈕,并在腳本中添加一定的附加功能,然后就可以為我們的房間添加額外的功能。
首先,我們來改變墻壁的顏色。在場景中,將另一個NearFieldButton放置在面板對象的上方,然后使其成為面板的子對象,以便當面板移動時,按鈕同樣會隨之移動。
接下來我們更新腳本以設置墻壁的顏色。
有兩個新的公共變量將在PanelController對象的Inspector中顯示為空字段。在Wall字段中,選擇當前用于墻壁的材質。如果對不想修改的其他對象使用相同的材質,則應復制墻壁材質并僅將其應用于墻壁。第二個字段是一個名為Color1的簡單顏色選擇器。只需選擇你喜歡的顏色即可。
回到腳本,我們有一個名為SetColor的簡單函數,它將對墻壁材質應用顏色。點擊1并從SetWallColor1函數啟動顏色更改。
最后一步是選擇新的NearFieldButton,然后再次配置函數調用,方法是單擊InteractiveStateChanged列表下的加號(+)按鈕,將PanelController對象拖動到顯示None(object)的打開字段中,然后選擇PanelController/RunSetWallColor1。
我已經將腳本設置成你可以根據需要多次復制/粘貼顏色變量和函數,以便為不同顏色設置多個按鈕。你同時可以使用類似的設置來調整skybox。方法是創建skybox材質的公共變量,并在按鈕觸發所選腳本函數時使用一個簡單的函數來設置它們。
當開始添加多個按鈕時,你可能需要在面板添加文本標記。我使用了TextMeshPro,它比Unity的內置UI文本要好得多。你只需通過Unity Registry將其安裝到Package Manager即可。
最終的房間控制裝置
8. 劇院模式和伸縮屋頂
現在所有一切已經準備妥當,你能夠觸發任何動畫或更改場景中任何對象的屬性。要制作一個可伸縮屋頂,我最終采用了與控制面板相同的步驟。訣竅是選擇代表屋頂的房間對象的面,然后將其分離以創建一個單獨的對象,這樣我就可以使用Boolean Tool并在其中創建一個大洞。
創建劇院模式涉及一個更為復雜的動畫,但就像其他動畫一樣,我通過設置時間軸和一次記錄一個對象的運動來建立動畫。我同時降低了房間里所有照明的亮度,使實際的電視屏幕縮放到適合房間的大小。
這里提供了我所有動畫和交互的最終腳本。
9. 下一步
我到了一個不得不停下來的時候。對于這個房間,我想做的事情沒有盡頭。在本教程中,我們確實將自己限制為僅觸發動畫或屬性更新。多虧了Unity動畫工具中內置的功能,我們可以走得很遠。
對于我的下一個項目,我想嘗試類似于在我們混合現實平臺中的新應用程序。這需要我們以新的方式使用物理對象。
原文鏈接:https://yivian.com/news/78527.html
轉載須知:轉載摘編需注明來源映維網并保留本文鏈接