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.
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 GetOrCreateArrComponent
de 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 RemoteEntitySyncObject
arquivo . 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);
}