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