Interagera med spelobjekt och komponenter i Unity
Azure Remote Rendering (ARR) är optimerad för ett stort antal objekt (se Begränsningar). Det är möjligt att hantera stora och komplexa hierarkier på värden, men det går inte att replikera dem alla i Unity på lågdrivna enheter.
När en modell läses in på värden speglar Azure Remote Rendering därför informationen om modellstrukturen på klientenheten (vilket medför nätverkstrafik), men replikerar inte objekten och komponenterna i Unity. I stället förväntar den sig att du begär nödvändiga Unity-spelobjekt och -komponenter manuellt, så att du kan begränsa omkostnaderna till vad som faktiskt behövs. På så sätt har du mer kontroll över prestanda på klientsidan.
Därför kommer Unity-integreringen av Azure Remote Rendering med ytterligare funktioner för att replikera fjärrrenderingsstrukturen på begäran.
Läsa in en modell i Unity
När du läser in en modell får du en referens till rotobjektet för den inlästa modellen. Den här referensen är inte ett Unity-spelobjekt, men du kan göra det till ett med hjälp av tilläggsmetoden Entity.GetOrCreateGameObject()
. Den funktionen förväntar sig ett argument av typen UnityCreationMode
. Om du skickar CreateUnityComponents
, fylls det nyligen skapade Unity-spelobjektet dessutom med proxykomponenter för alla fjärrrenderingskomponenter som finns på värden. Vi rekommenderar dock att du föredrar DoNotCreateUnityComponents
att hålla omkostnaderna minimala.
Läsa in modell med Unity-coroutines
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);
}
}
Belastningsmodell med inväntningsmönster
async void LoadModelWithAwait(RenderingSession session)
{
var result = await session.Connection.LoadModelFromSasAsync(new LoadModelFromSasOptions("builtin://Engine"), null);
var gameObject = result.Root?.GetOrCreateGameObject(UnityCreationMode.DoNotCreateUnityComponents);
}
Kodexemplen ovan använde modellens inläsningssökväg via SAS eftersom den inbyggda modellen har lästs in. Att hantera modellen via blobcontainrar (med hjälp av LoadModelAsync
och LoadModelOptions
) fungerar helt analogt.
RemoteEntitySyncObject
När du skapar ett Unity-spelobjekt läggs en RemoteEntitySyncObject
komponent till i spelobjektet implicit. Den här komponenten används för att synkronisera entitetstransformningen till servern. Som standard RemoteEntitySyncObject
kräver användaren att uttryckligen anropa SyncToRemote()
för att synkronisera det lokala Unity-tillståndet till servern. Om du aktiverar SyncEveryFrame
synkroniseras objektet automatiskt.
Objekt med en RemoteEntitySyncObject
kan få sina fjärrbarn instansierade och visas i Unity-redigeraren via Show children knappen.
Omslutningskomponenter
Komponenter som är anslutna till fjärrrenderingsentiteter exponeras för Unity via proxy MonoBehavior
s. Dessa proxyservrar representerar fjärrkomponenten i Unity och vidarebefordrar alla ändringar till värden.
Om du vill skapa fjärrrenderingskomponenter för proxy använder du tilläggsmetoden GetOrCreateArrComponent
:
var cutplane = gameObject.GetOrCreateArrComponent<ARRCutPlaneComponent>(RemoteManagerUnity.CurrentSession);
Kopplade livslängder
Livslängden för en fjärrentitet och ett Unity-spelobjekt är kopplat medan de är bundna via en RemoteEntitySyncObject
. Om du anropar UnityEngine.Object.Destroy(...)
med ett sådant spelobjekt tas även fjärrentiteten bort.
Om du vill förstöra Unity-spelobjektet, utan att påverka fjärrentiteten, måste du först anropa Unbind()
RemoteEntitySyncObject
.
Detsamma gäller för alla proxykomponenter. Om du bara vill förstöra representationen på klientsidan måste du anropa Unbind()
proxykomponenten först:
var cutplane = gameObject.GetComponent<ARRCutPlaneComponent>();
if (cutplane != null)
{
cutplane.Unbind();
UnityEngine.Object.Destroy(cutplane);
}