Interactie met Unity-gameobjecten en -onderdelen

Azure Remote Rendering (ARR) is geoptimaliseerd voor een groot aantal objecten (zie Beperkingen). Hoewel het mogelijk is om grote en complexe hiërarchieën op de host te beheren, is het niet mogelijk om ze allemaal in Unity te repliceren op apparaten met weinig energie.

Wanneer een model op de host wordt geladen, wordt in Azure Remote Rendering de informatie over de modelstructuur op het clientapparaat gespiegeld (waardoor netwerkverkeer wordt gemaakt), maar worden de objecten en onderdelen in Unity niet gerepliceerd. In plaats daarvan verwacht het dat u handmatig de benodigde Unity-gameobjecten en -onderdelen aanvraagt, zodat u de overhead kunt beperken tot wat er daadwerkelijk nodig is. Op deze manier hebt u meer controle over de prestaties aan de clientzijde.

Daarom wordt de Unity-integratie van Azure Remote Rendering geleverd met extra functionaliteit om de Remote Rendering-structuur op aanvraag te repliceren.

Een model laden in Unity

Wanneer u een model laadt, krijgt u een verwijzing naar het hoofdobject van het geladen model. Deze verwijzing is geen Unity-gameobject, maar u kunt het omzetten in een object met behulp van de extensiemethode Entity.GetOrCreateGameObject(). Deze functie verwacht een argument van het type UnityCreationMode. Als u doorgeeft CreateUnityComponents, wordt het zojuist gemaakte Unity-gameobject ook gevuld met proxyonderdelen voor alle Remote Rendering-onderdelen die op de host aanwezig zijn. Het wordt echter aanbevolen om de overhead minimaal te DoNotCreateUnityComponentshouden.

Model laden met 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);
    }
}

Load model with await pattern

async void LoadModelWithAwait(RenderingSession session)
{
    var result = await session.Connection.LoadModelFromSasAsync(new LoadModelFromSasOptions("builtin://Engine"), null);
    var gameObject = result.Root?.GetOrCreateGameObject(UnityCreationMode.DoNotCreateUnityComponents);
}

De bovenstaande codevoorbeelden hebben het laadpad van het model via SAS gebruikt omdat het ingebouwde model wordt geladen. Het adresseren van het model via blobcontainers (met behulp LoadModelAsync en LoadModelOptions) werkt volledig analoog.

RemoteEntitySyncObject

Als u een Unity-gameobject maakt, wordt impliciet een RemoteEntitySyncObject onderdeel aan het gameobject toegevoegd. Dit onderdeel wordt gebruikt om de entiteitstransformatie te synchroniseren met de server. RemoteEntitySyncObject Standaard moet de gebruiker expliciet aanroepen SyncToRemote() om de lokale Unity-status te synchroniseren met de server. Als u het object inschakelt SyncEveryFrame , wordt het object automatisch gesynchroniseerd.

Objecten met een RemoteEntitySyncObject kunnen hun externe kinderen geïnstantieerd en weergegeven in de Unity-editor via de Show children knop.

RemoteEntitySyncObject

Wrapper-onderdelen

Onderdelen die zijn gekoppeld aan Remote Rendering-entiteiten, worden via proxy's MonoBehaviorblootgesteld aan Unity. Deze proxy's vertegenwoordigen het externe onderdeel in Unity en sturen alle wijzigingen naar de host door.

Als u proxy Remote Rendering-onderdelen wilt maken, gebruikt u de extensiemethode GetOrCreateArrComponent:

var cutplane = gameObject.GetOrCreateArrComponent<ARRCutPlaneComponent>(RemoteManagerUnity.CurrentSession);

Gekoppelde levensduur

De levensduur van een externe entiteit en een Unity-gameobject is gekoppeld terwijl ze zijn gebonden via een RemoteEntitySyncObject. Als u een dergelijk gameobject aanroept UnityEngine.Object.Destroy(...) , wordt de externe entiteit ook verwijderd.

Als u het Unity-gameobject wilt vernietigen, zonder dat dit van invloed is op de externe entiteit, moet u eerst het RemoteEntitySyncObjectaanroepenUnbind().

Hetzelfde geldt voor alle proxyonderdelen. Als u alleen de weergave aan de clientzijde wilt vernietigen, moet u eerst het proxyonderdeel aanroepen Unbind() :

var cutplane = gameObject.GetComponent<ARRCutPlaneComponent>();
if (cutplane != null)
{
    cutplane.Unbind();
    UnityEngine.Object.Destroy(cutplane);
}

Volgende stappen