Stage
概述
Fusion舞台 範例展示了一個方法,以透過Fusion開發針對最多達200名玩家的社交應用程式。
各個玩家由一個虛擬人偶所代表,並且如果他們位於相同的聊天氣泡中,就可以利用Photon Voice SDK來和其他玩家交談。
同時一個使用者可以登上舞台並且開始呈現內容。
這個範例的一些聚焦點是:
- 首先,玩家在選擇虛擬人偶畫面中客製化其虛擬人偶,
- 然後,它們可以加入舞台場景。如果玩家在一個PC或MAC上啟動範例,它可以選擇桌面模式(使用鍵盤及滑鼠)或VR模式(Meta Quest頭戴式裝置)。
- 如果玩家位於相同的靜態聊天氣泡中,就可以彼此交談。在各個靜態聊天氣泡中,可用一個鎖定按鈕來預防新的玩家進入。
- 一個使用者可以登上舞台,而且以這個方式在房間中對所有玩家說話。然後這個使用者可以增加被允許和他一起站在舞台的使用者數量。
- 發言者聲音不再被空間化,所以每個人可以從喇叭聽到它們。
- 這裡,可以分享內容,比如在所有使用者之間同步播放的影片。
- 一個舞台相機系統跟隨發言者,以在專用畫面上顯示他
- 一旦入座後,一個使用者可以要求與舞台上的發言者對話。如果發言者接受,那麼每個人都會聽到發言者和該使用者的對話,直到發言者或使用者決定停止對話。
- 同時,在觀眾中的人可以透過發送表情符號在發言時表達他們的意見。
在程式碼評論中直接提供更多技術細節。
技術資訊
- 這個範例使用共享模式拓撲,
- 組建可用於PC、Mac及Meta Quest,
- 專案已透過Unity 2021.3.10f1、Fusion 1.1.3f 599及Photon voice 2.31開發,
- 支援2個虛擬人偶解決方案(自製的簡單虛擬人偶及Ready Player Me 1.9.0虛擬人偶),
在您開始之前
為了運行範例:
在PhotonEngine儀表板中建立一個Fusion應用程式帳號,並且將它貼上到即時設定(可從Fusion選單中到達)中的
App Id Fusion
欄位之中。在PhotonEngine儀表板中建立一個Voice應用程式帳號,並且將它貼上到即時設定中的
App Id Voice
欄位之中然後載入
AvatarSelection
場景並且按下Play
下載
版本 | 發佈日期 | 下載 | ||
---|---|---|---|---|
0.0.18 | 2022年11月3日 | Fusion舞台0.0.18組建70 |
下載二進位檔
下方是可用的一個舞台的展示版本:
處理輸入
桌面
鍵盤
- 移動:WASD或ZQSD以行走
- 旋轉:QE或AE以旋轉
滑鼠
- 移動:按下您的滑鼠左鍵以顯示一個指標。您將在放開時傳送到任何已接受目標
- 旋轉:持續按下滑鼠右鍵並且移動滑鼠以旋轉視角
- 移動及旋轉:持續按下滑鼠左鍵及右鍵以向前移動。您仍然可以移動滑鼠以旋轉
- 拿取:將滑鼠放在物件上,並且使用滑鼠左鍵來拿取它。
Meta Quest
- 傳送:按下A、B、X、Y,或任何搖桿以顯示一個指標。您將在放開時傳送到任何已接受目標
- 觸碰(也就是針對聊天氣泡鎖定按鈕):簡單地將您的手放在一個按鈕上以切換它
- 拿取:首先將您的手放在物件上,並且使用控制器拿取按鈕來拿取它
資料夾架構
主要資料架/Stage
含有特定於這個範例的所有元素。
資料夾/IndustriesComponents
含有與Fusion Expo範例/共享的元件
/Photon
資料夾含有Fusion及Photon Voice SDK。
/Photon/FusionXRShared
資料夾含有來自VR共享範例的裝置及拿取邏輯,它建立一個FusionXR共享輕量SDK,其可以與其他專案共享。
/Photon/FusionXRShared/Extensions
資料夾含有針對FusionXR共享的延伸模組,針對可重複使用的功能比如已同步射線、運動驗證...
/Plugins
資料夾含有Ready Player Me SDK
/StreamingAssets
資料夾含有預先組建的ReadyPlayerMe虛擬人偶。如果您不希望使用這些預先組建的虛擬人偶,它可以被自由移除。
/XR
資料夾含有針對虛擬實境的設置檔案。
架構概述
Fusion 舞台仰賴於與VR共享頁面中描述的相同的程式碼基礎,特別是在裝置同步方面。
這裡使用的拿取系統是在VR共享——本機裝置拿取頁面中描述的替代性「本機裝置拿取」執行方式。
在這個基礎之外,如同Expo範例,本範例含有一些到FusionXR共享的延伸程式,以處理一些可重複使用的功能,比如已同步射線、運動驗證、觸碰、傳送平順或一個凝視系統。
此外,Fusion舞台範例共享Fusion Expo範例程式碼的一個大的部分,其中包含聊天氣泡。
舞台
舞台使用一個Zone
,如同聊天氣泡中所使用的(請參見Fusion Expo範例)。
預設下,這個區最大容量為1位使用者,因此防止發言人已經在舞台上時其他人來到舞台上。但是發言人可以透過舞台主控台來更改這個值。
為了確保針對所有使用者來適當地顯示該使用者,針對任何進入舞台的使用者,也在StageZone.ForceUserLOD()
中停用了LODGroup,以確保沒有LOD將觸發它們。
聲音
與舞台區相關的聲音群,是特殊聲音群「0」,其預設可以被任何玩家聽見。
ZoneAudioInterestChanger
在進入一個區時處理聲音群切換,其也決定是否使用這個特殊全域群。在這個案例中,如果Zone.IsGlobalAudioGroup()
在ZoneAudioInterestChanger.ManageAudioSources()
中傳回真:
- 它強制啟用任何進入這個區的使用者的聲音源
- 它移除聲音源空間化,這樣這個使用者的聲音在房間的任何角落都可以聽見。
發言者相機
在舞台上發言者相機跟隨使用者。為了做到這點,針對舞台區,StageZone
類別註冊為一個IZoneListener
接聽器,並且當一位使用者在舞台上時觸發相機追蹤及記錄。
StageZone
可以處理多個相機,並且針對各個發言者將觸發跟隨發言者的移動,同時只針對最相關的相機來啟用實際轉譯。這些相機有以秒來轉譯的幀的較低的計數,這是在StageCamera
類別中完成的,同時也完成相機移動。相機相對於一個相機裝置Transform
來放置,並且沿著這個轉換的x
軸來移動。
座位
為了減少一名使用者共享的資料數量,在他們入座後可以較少重新整理它們的虛擬人偶同步。
為了做到這點,HardwareRig
子類別StageHardwareRig
可以接收入座請求(由SeatDetector
類別觸發,其在使用者在一個座位上傳送時進行觀察):當一名使用者入座後,將較少更新輸入。這樣做的話,StageNetworkRig
NetworkRig
子類別將較少更新NetworkTransform
位置,因此發送較少資料。
為了停用這個選擇性最佳化,可以在StageHardwareRig
上設定freezeForRemoteClientsWhenSeated
為假。
參與者舞台聲音存取
會議參與者可以請求存取舞台麥克風。舞台上的發言者可以允許它們或是拒絕它們的請求。
一位使用者的已連線裝置含有一個VoiceableAttendee
元件,其主控一個[Networked]
變數AttendeeStatus
。這個狀態描述:
- 如果還沒有做成任何請求,
- 如果觀眾正在要求到舞台的聲音存取,
- 如果它已經被接受,
- 如果它已經被接受,但是它們被短暫地靜音,
- 或是如果請求已經被拒絕,
當使用者以他們的UI來請求聲音存取,(1)在上述圖表中,它們的狀態被更新 (2),並且網路變數同步它到所有使用者 (3)。它在所有客戶端上觸發一個回調 (4) ,其警示一個儲存所有參與者的AttendeeRegistry
元件,並且其廣播這個更改資訊給其所有接聽者 (5)。
在這個方法下,與舞台上的展台相關的AttendeeRequestHandler
可以儲存一個正在請求的參與者的清單,並且相應地更新其UI。一個[Networked]
變數, SelectedRequestingAttendeeInfo
持有關於在UI中的選中的參與者的資訊,這樣同步在各個客戶端上的每個UI。
當發言者驗證一個聲音請求 (6),改變了SelectedRequestingAttendeeInfo
參與者狀態資訊。不可以直接地更改VoiceableAttendee
AttendeeStatus
,因為發言者可能不是請求者,並且因此沒有狀態授權裝置的已連線物件。但是因為SelectedRequestingAttendeeInfo
是一個[Networked]
變數,針對發言者來本機地更改它 (7) 將在所有客戶端上觸發一個更新 (8)。在這個更新期間,各個客戶端檢查它是否是VoiceableAttendee
已連線物件的狀態授權,並且如果它是的話,則更改參與者狀態 (9)。
最後,更改這個狀態將在所有客戶端上觸發VoiceableAttendee
AttendeeStatus
的一個更新,並且可以看見現在觀眾是一個有聲音的觀眾,它可以 (10):
- 透過
ZoneAudioInterestChanger
(已經在發言者舞台的聊天氣泡中使用:舞台只是一個特殊Zone
),針對所有使用者來啟用它們的聲音。針對有聲音的參與者來觸發它的OnZoneChanged
,就像他們已經進入了舞台Zone
一樣,從而啟用他們的聲音。 - 在
AvatarRepresentation
中針對這個使用者來停用LOD群,這樣他們針對所有人都顯示最大的細節,就像在舞台上的發言者。
影片同步
影片播放器目前是一個簡單的Unity影片播放器,但是可以使用任何影片庫。
在舞台上的發言人可以在舞台的主控台上開始、前往一個特定的時間,或暫停影片。為了針對所有使用者來同步這個,VideoControl
NetworkBehaviour
含有一個PlayState
[Networked]
架構,其持有遊玩狀態及位置。作為一個已連線變數,當它被使用UI的發言者更改,在所有客戶端上也觸發更改回調,其允許它們在它們自己的播放器上應用更改。
表情符號
在聲音請求之外,在任何時間,觀眾可以透過發送表情符號來表達意見。
因為該功能對於這個使用案例而言並不是必要的,當一位使用者按一下表情符號UI按鈕時,我們使用RPC來繁衍相關的預製件。這意味著進入房間的一位新的使用者將不會看見先前已生成的表情符號(表情符號幾秒鐘後就消失了)。
同時,我們認為沒有必要在空間中同步表情符號的位置,因此表情符號預製件不是已連線物件。
EmotesRequest
類別位於觀眾UI上,其負責請求EmotesSpawner
類別以在使用者的位置上繁衍一個表情符號。
因為需要一個已連線物件,EmotesSpawner
位於使用者的網路裝置上。
第三方元件
- Oculus整合
- Oculus唇型同步
- Oculus範例框架手
- Ready player me
- 聲音
更改記錄
Fusion 舞台 0.0.18
- 當發生一個網路問題時,修復錯誤訊息顯示
Fusion 舞台 0.0.17
- 更新到Fusion SDK 1.1.3 F 組建 599