VR Shared - Meta Avatars integration
概述
這個範例的範圍是說明如何在一個Fusion應用程式中使用共享拓撲來整合Meta虛擬人偶。
主要關注點是為了:
- 使用Fusion已連網變數來同步虛擬人偶
- 以Fusion聲音來整合唇形同步
技術資訊
這個範例使用 共享模式 拓撲,
專案已經透過以下內容來開發:
- Unity 2021.3.23f1
- Oculus XR外掛程式3.3.0
- Meta虛擬人偶SDK 18.0
- Photon Fusion 1.1.3f 599
- Photon聲音2.50
在您開始之前
為了運行範例:
在Photon引擎儀表板建立一個Fusion應用程式帳號,並將它貼上到Real Time設定中的
App Id Fusion
欄位(可從Fusion選單到達)。在Photon引擎儀表板建立一個Voice應用程式帳號,並將它貼上到Real Time設定中的
App Id Voice
欄位然後載入
Scenes\OculusDemo\Demo
場景並且按下Play
下載
版本 | 發布日期 | 下載 | ||
---|---|---|---|---|
1.1.3 | 2023年5月5日 | Fusion VR共享Meta虛擬人偶整合1.1.3組建191 |
處理輸入
Meta Quest
- 傳送:按下A、B、X、Y,或任何搖桿以顯示一個指標。您將放開時傳送到任何已接受的目標。
- 拿取:首先將您的手放到物件上,然後使用控制器拿取按鈕來拿取它
範例支援Meta手追蹤。所以,您可以使用捏合手勢來傳送或拿取一個物件。
資料夾架構
/Oculus
資料夾含有Meta SDK。
/Photon
資料夾含有Fusion及Photon聲音SDK。
/Photon/FusionXRShared
資料夾含有來自VR共享範例的裝備及拿取邏輯,其建立一個FusionXR共享輕量SDK,其可以與其他專案共享。
/Photon/FusionXRShared/Extensions
資料夾含有針對FusionXR共享的,針對可重複使用的功能比如已同步光線或運動驗證等等的擴展程式。
/Photon/FusionXRShared/Extensions/OculusIntegration
資料夾含有針對Meta SDK整合來開發的預製件及指令碼。
/StreamingAssets
資料夾含有預先組建的Meta虛擬人偶。
/XR
資料夾含有針對虛擬實境的設置檔案。
架構概述
為了了解設定裝備的方式,或任何與這個範例有關的細節,請先參照主要VR共享頁面。
場景設定
OVR硬體裝備
場景含有一個硬體裝備,其與Oculus SDK相容。次物件MetaAvatar
包含與Meta虛擬人偶相關的所有事情。
LipSync
有OVRAvatarLipSyncContext
元件:其由Oculus SDK提供以設定唇形同步功能。BodyTracking
有SampleInputManager
元件:它來自於Oculus SDK (Asset/Avatar2/Example/Common/Scripts
)。它是來自OvrAvatarInputManager
基礎類別的衍生類別,並且它指的是在一個虛擬人偶實體上設定追蹤輸入的OVR Hardware Rig
。AvatarManager
有OVRAvatarManager
元件:它用於載入Meta虛擬人偶。
連線管理器
ConnectionManager
處理到Photon Fusion伺服器的連線,並且在調用OnPlayerJoined
回調時生成使用者網路預製件。
為了透過網路來串流聲音,我們需要Fusion Voice Client
。主要記錄器欄位指位於ConnectionManager
之下的Recorder
遊戲物件。
如需取得更多關於Photon聲音與Fusion整合的細節,請參見這個頁面:聲音 - Fusion整合。
ConnectionManager
遊戲物件也負責透過MicrophoneAuthorization
元件來請求麥克風授權。它在授與麥克風存取時啟用Recorder
物件。
次物件Recorder
負責連線到麥克風。它含有AudioLipSyncConnector
元件,其從Recorder
接收聲音串流並且轉傳它到OVRAvatarLipSyncContext
AudioSource
及UpdateConnectionStatus
是可選的。它在INetworkRunner
回調事件上給予聲音回饋。
為使用者生成的網路預製件
當調用OnPlayerJoined
回調時,ConnectionManager
生成使用者網路預製件OculusAvatarNetworkRig Variant
。
這個預製件含有:
MetaAvatarSync
:它負責在啟動時選擇一個隨機的虛擬人偶,並且透過網路來串流虛擬人偶。NetworkedAvatarEntity
:它衍生自OculusOvrAvatarEntity
。它用於設置虛擬人偶實體,其取決於網路裝備是代表本機使用者或遠端使用者。
虛擬人偶同步
當生成使用者已連網預製件時,MetaAvatarSync
選擇一個隨機的虛擬人偶。
C#
AvatarIndex = UnityEngine.Random.Range(0, 31);
Debug.Log($"Loading avatar index {AvatarIndex}");
avatarEntity.SetAvatarIndex(AvatarIndex);
因為AvatarIndex
是一個已連網變數,所有玩家將在這個值改變時被更新。
C#
[Networked(OnChanged = nameof(OnAvatarIndexChanged))]
int AvatarIndex { get; set; } = -1;
C#
static void OnAvatarIndexChanged(Changed<MetaAvatarSync> changed)
{
changed.Behaviour.ChangeAvatarIndex();
}
在硬體裝備上的SampleInputManager
元件追蹤使用者的移動。
如果玩家網路裝備代表本機玩家,它由NetworkedAvatarEntity
參照。
這個設定由MetaAvatarSync
(ConfigureAsLocalAvatar()
)完成。
在各個LateUpdate()
,MetaAvatarSync
針對本機玩家來捕捉虛擬人偶資料。
C#
private void LateUpdate()
{
// Local avatar has fully updated this frame and can send data to the network
if (Object.HasInputAuthority)
{
CaptureAvatarData();
}
}
CaptureLODAvatar
方法取得虛擬人偶實體串流緩衝,並且複製它到一個名為AvatarData
的網路變數之中。
容量被限制為1200,因為這足夠在中等或高LOD中串流Meta虛擬人偶。
請注意,為了簡化,在這個範例中我們只串流中等LOD。
緩衝大小AvatarDataCount
也透過網路同步。
C#
[Networked(OnChanged = nameof(OnAvatarDataChanged)), Capacity(1200)]
public NetworkArray<byte> AvatarData { get; }
[Networked]
public uint AvatarDataCount { get; set; }
所以,當更新虛擬人偶串流緩衝時,將告知遠端使用者,並且在代表遠端使用者的網路裝備上應用已接收資料。
C#
static void OnAvatarDataChanged(Changed<MetaAvatarSync> changed)
{
changed.Behaviour.ApplyAvatarData();
}
載入已個人化的Meta虛擬人偶
載入本機使用者虛擬人偶
為了載入本機使用者虛擬人偶,在已生成回調期間,如果網路物件被關聯到本機使用者,NetworkedAvatarEntity
以LoadLoggedInUserCdnAvatar()
來請求使用者的帳號虛擬人偶。
C#
/// <summary>
/// Load the user meta avatar, and store its user id in the associated listener
/// Note: _deferLoading has to been set to true for this to be working
/// </summary>
async void LoadUserAvatar(NetworkedAvatarEntity.IUserIdListener listener)
{
Debug.Log("Loading Cdn avatar...");
LoadLoggedInUserCdnAvatar();
while (_userId == 0)
{
await Task.Delay(100);
}
Debug.Log("Avatar UserId: " + _userId);
if(listener != null)
listener.UserId = _userId;
}
這個方法設定使用者ID,其是一個[已連網]變數,這樣的話使用者ID將在所有客戶端上被同步。
C#
[Networked(OnChanged = nameof(OnUserIdChanged))]
public ulong UserId { get; set; }
請注意,為了能夠載入使用者虛擬人偶:
Defer Loading
應該在玩家的預製件的NetworkedAvatarEntity
元件上被設定為真:它將防止虛擬人偶在啟動時被自動載入。- 針對將被調用的
LoadUserAvatar()
,syncUserIdAvatar
必須在NetworkedAvatarEntity
元件上被設定為真(如果syncUserIdAvatar
被設定為偽,並且Defer Loading
也被設定為偽,將自動載入一個隨機的本機虛擬人偶)。
載入遠端使用者的虛擬人偶
在接收到UserId
時,遠端使用者將觸發與這個ID關聯的虛擬人偶的下載:
C#
static void OnUserIdChanged(Changed<MetaAvatarSync> changed)
{
changed.Behaviour.OnUserIdChanged();
}
void OnUserIdChanged()
{
if(Object.HasStateAuthority == false)
{
Debug.Log("Loading remote avatar: "+UserId);
avatarEntity.LoadRemoteUserCdnAvatar(UserId);
}
}
###存取到Meta虛擬人偶
為了能夠載入Meta虛擬人偶,您必須要在Oculus > Oculus Platform
Unity設定選單之中,針對您的應用程式來新增App Id
。
可以在您的Meta儀表板上的API > App Id
欄位中找到這個App Id
。
同時,這個應用程式必須有一個已完成的Data use checkup
部分,其已經請求User Id
、User profile
及Avatars
存取:
測試使用者的虛擬人偶
為了能夠在開發中看見與本機Meta帳戶關聯的虛擬人偶,本機使用者帳戶必須是與Oculus平台設定中提供的App Id
關聯的組織的成員。
為了在跨平台設定中看見您的虛擬人偶(在一個Quest與一個桌面組建之間),您需要將您的Quest及Rift應用程式進行群組,如同在這個頁面上的Group App IDs Together
章節中所說明:針對Meta虛擬人偶SDK來設置應用程式
唇形同步
麥克風初始化由Photon Voice Recorder
完成。
設置在OVRHardwareRig
上的OvrAvatarLipSyncContext
為期待直接調用,以向其提供聲音緩衝。
一個類別掛鉤在記錄器聲音讀取,以轉傳它到OvrAvatarLipSyncContext
,如同下述。
Recorder
類別可以轉傳讀取聲音緩衝到執行IProcessor
介面的類別。
如需更多關於如何建立一個自訂聲音處理器的細節,請參見這個頁面:Photon聲音 - 問與答。
為了註冊這個在聲音連線中的處理器,一個VoiceComponent
子類別,AudioLipSyncConnector
,被新增在與Recorder
相同的遊戲物件上。
這導致接收PhotonVoiceCreated
及PhotonVoiceRemoved
回調,其允許新增一個後處理器到已連線聲音。
已連線後處理器是一個AvatarAudioProcessor
,其執行IProcessor<float>
。
在一個玩家連線中,MetaAvatarSync
元件搜尋位於Recorder
上的AudioLipSyncConnector
,以設定這個處理器的lipSyncContext
欄位。
這樣做的話,每次Recorder
調用AvatarAudioProcessor Process
回調的時候,以接收到的聲音緩衝來調用在OvrAvatarLipSyncContext
上的ProcessAudioSamples
,其確保在虛擬人偶模型上計算唇形同步。
這樣做的話,在MetaAvatarSync
的後期更新期間,以虛擬人偶實體上的RecordStreamData_AutoBuffer
來捕捉時,唇形同步將與其他虛擬人偶的身體資訊一起串流。
繼續
所以繼續,利用MetaAvatarSync
ConfigureAsLocalAvatar()
方法,當針對本機使用者來生成使用者網路預製件時,關聯的NetworkAvatarEntity
從以下地方來接收資料:
OvrAvatarLipSyncContext
,針對唇形同步SampleInputManager
,針對身體追蹤
資料利用已連網變數,透過網路來串流。
當為了遠端使用者來生成使用者網路預製件時,調用MetaAvatarSync
ConfigureAsRemoteAvatar()
,並且關聯的NetworkAvatarEntity
類別將根據串流的資料來構建及動畫化虛擬人偶。