Interagir com objetos e componentes de jogos do Unity

A Renderização Remota do Azure (ARR) é otimizada para um grande número de objetos (consulte Limitações). Embora seja possível gerenciar hierarquias grandes e complexas no host, replicá-las todas no Unity em dispositivos de baixa potência é inviável.

Portanto, quando um modelo é carregado no host, a Renderização Remota do Azure espelha as informações sobre a estrutura do modelo no dispositivo cliente (que incorrerá em tráfego de rede), mas não replica os objetos e componentes no Unity. Em vez disso, ele espera que você solicite os objetos e componentes necessários do jogo Unity manualmente, de modo que você possa limitar a sobrecarga ao que é realmente necessário. Dessa forma, você tem mais controle sobre o desempenho do lado do cliente.

Consequentemente, a integração Unity da Renderização Remota do Azure vem com funcionalidade adicional para replicar a estrutura de Renderização Remota sob demanda.

Carregar um modelo no Unity

Ao carregar um modelo, você obtém uma referência ao objeto raiz do modelo carregado. Esta referência não é um objeto de jogo Unity, mas você pode transformá-lo em um usando o método Entity.GetOrCreateGameObject()de extensão . Essa função espera um argumento do tipo UnityCreationMode. Se você passar CreateUnityComponents, o objeto de jogo Unity recém-criado também será preenchido com componentes proxy para todos os componentes de renderização remota existentes no host. Recomenda-se, no entanto, preferir DoNotCreateUnityComponents, manter a sobrecarga mínima.

Modelo de carga com co-rotinas 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);
    }
}

Modelo de carregamento com padrão de espera

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

Os exemplos de código acima usaram o caminho de carregamento do modelo via SAS porque o modelo interno é carregado. Endereçar o modelo através de contêineres de blob (usando LoadModelAsync e LoadModelOptions) funciona totalmente de forma análoga.

RemoteEntitySyncObject

Criar um objeto de jogo Unity adiciona implicitamente um RemoteEntitySyncObject componente ao objeto de jogo. Este componente é usado para sincronizar a transformação de entidade com o servidor. Por padrão RemoteEntitySyncObject , requer que o usuário chame SyncToRemote() explicitamente para sincronizar o estado Unity local com o servidor. A ativação SyncEveryFrame sincronizará o objeto automaticamente.

Objetos com um RemoteEntitySyncObject podem ter seus filhos remotos instanciados e mostrados no editor Unity através do Show children botão.

RemoteEntitySyncObject

Componentes do invólucro

Os componentes anexados a entidades de renderização remota são expostos ao Unity por meio de proxys MonoBehavior. Esses proxies representam o componente remoto no Unity e encaminham todas as modificações para o host.

Para criar componentes de renderização remota de proxy, use o método GetOrCreateArrComponentde extensão :

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

Tempo de vida acoplado

O tempo de vida de uma entidade remota e um objeto de jogo Unity é acoplado enquanto eles estão ligados através de um RemoteEntitySyncObjectarquivo . Se você ligar UnityEngine.Object.Destroy(...) com esse objeto de jogo, a entidade remota também será removida.

Para destruir o objeto do jogo Unity, sem afetar a entidade remota, você primeiro precisa chamar Unbind() o RemoteEntitySyncObject.

O mesmo é verdadeiro para todos os componentes de proxy. Para destruir apenas a representação do lado do cliente, você precisa chamar Unbind() o componente proxy primeiro:

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

Próximos passos