Interakce s herními objekty a komponentami Unity
Azure Remote Rendering (ARR) je optimalizovaný pro velký počet objektů (viz Omezení). I když je možné spravovat velké a složité hierarchie na hostiteli, replikace všech v Unity na zařízeních s nízkým využitím je neproveditelná.
Proto když je na hostiteli načten model, Azure Remote Rendering zrcadlí informace o struktuře modelu na klientském zařízení (což bude mít za následek síťový provoz), ale nereplikuje objekty a komponenty v Unity. Místo toho očekává, že budete vyžadovat potřebné herní objekty a komponenty Unity ručně, abyste mohli omezit režii na to, co je skutečně potřeba. Díky tomu máte větší kontrolu nad výkonem na straně klienta.
V důsledku toho integrace Unity služby Azure Remote Rendering nabízí další funkce pro replikaci struktury vzdáleného vykreslování na vyžádání.
Načtení modelu v Unity
Při načítání modelu získáte odkaz na kořenový objekt načteného modelu. Tento odkaz není herní objekt Unity, ale můžete jej změnit na jeden pomocí rozšiřující metody Entity.GetOrCreateGameObject()
. Tato funkce očekává argument typu UnityCreationMode
. Pokud projdete CreateUnityComponents
, nově vytvořený herní objekt Unity se navíc naplní komponentami proxy pro všechny komponenty vzdáleného vykreslování, které existují na hostiteli. Doporučuje se ale raději DoNotCreateUnityComponents
udržet režijní náklady minimální.
Načtení modelu s koruteny Unity
IEnumerator LoadModelWithCoroutine(RenderingSession session)
{
float currentProgress = 0.0f;
var task = session.Connection.LoadModelFromSasAsync(new LoadModelFromSasOptions("builtin://Engine"),
(float progress) =>
{
currentProgress = progress;
});
while (!task.IsCompleted && !task.IsFaulted)
{
int percentage = (int)(currentProgress * 100.0f);
yield return null;
}
if (!task.IsFaulted)
{
var gameObject = task.Result.Root?.GetOrCreateGameObject(UnityCreationMode.DoNotCreateUnityComponents);
}
}
Model načtení s modelem await
async void LoadModelWithAwait(RenderingSession session)
{
var result = await session.Connection.LoadModelFromSasAsync(new LoadModelFromSasOptions("builtin://Engine"), null);
var gameObject = result.Root?.GetOrCreateGameObject(UnityCreationMode.DoNotCreateUnityComponents);
}
Výše uvedené ukázky kódu použily cestu načítání modelu prostřednictvím SAS, protože je načten integrovaný model. Řešení modelu prostřednictvím kontejnerů objektů blob (pomocí LoadModelAsync
a LoadModelOptions
) funguje plně podobně.
RemoteEntitySyncObject
Vytvoření herního objektu Unity implicitně přidá RemoteEntitySyncObject
komponentu do herního objektu. Tato komponenta slouží k synchronizaci transformace entity na server. Ve výchozím nastavení RemoteEntitySyncObject
vyžaduje, aby uživatel explicitně volal SyncToRemote()
, aby synchronizoval místní stav Unity se serverem. Povolením SyncEveryFrame
se objekt automaticky synchronizuje.
Objekty s RemoteEntitySyncObject
můžou mít instanci vzdálených podřízených objektů a zobrazit je v editoru Show children Unity pomocí tlačítka.
Součásti obálky
Komponenty připojené k entitám vzdáleného vykreslování jsou zpřístupněny Unity prostřednictvím proxy serverů MonoBehavior
. Tyto proxy servery představují vzdálenou komponentu v Unity a předávají všechny úpravy hostitele.
Chcete-li vytvořit komponenty vzdáleného vykreslování proxy serveru, použijte metodu GetOrCreateArrComponent
rozšíření:
var cutplane = gameObject.GetOrCreateArrComponent<ARRCutPlaneComponent>(RemoteManagerUnity.CurrentSession);
Párované životnosti
Životnost vzdálené entity a herního objektu Unity je svázána, když jsou vázány pomocí RemoteEntitySyncObject
. Pokud zavoláte UnityEngine.Object.Destroy(...)
s takovým herním objektem, odebere se i vzdálená entita.
Chcete-li zničit herní objekt Unity, aniž by to ovlivnilo vzdálenou entitu, musíte nejprve volat Unbind()
na RemoteEntitySyncObject
objekt .
Totéž platí pro všechny komponenty proxy serveru. Pokud chcete zničit pouze reprezentaci na straně klienta, musíte nejprve volat Unbind()
komponentu proxy serveru:
var cutplane = gameObject.GetComponent<ARRCutPlaneComponent>();
if (cutplane != null)
{
cutplane.Unbind();
UnityEngine.Object.Destroy(cutplane);
}