Partilhar via


Guia do programador de Scripts na Cloud

Este guia descreve como utilizar a API de Scripting na Cloud do Mesh e as ferramentas de programador para criar Ambientes (estes começam como projetos no Unity e, em seguida, são carregados para uma Coleção de Malha). Recomendamos que leia primeiro a infraestrutura Definir Scripting na cloud no Azure para se familiarizar com os conceitos e a arquitetura básica do Mesh Cloud Scripting.

Esta secção descreve as funcionalidades e a interface da API mesh Cloud Scripting, que é utilizada para escrever os scripts que impulsionam comportamentos em Ambientes.

Estrutura do DOM básico

A estrutura DOM espelha a estrutura da sua cena do Unity. O membro "Cena" da aplicação corresponde ao objeto de jogo ao qual o componente Mesh Cloud Scripting está anexado. As seguintes classes de API de Scripting na Cloud do Mesh mapeiam um-para-um com objetos do Unity criados no editor:

  • GameObject (& Transform Component) -> TransformNode
  • Componente Claro -> PointLightNode, SpotLightNode, DirectionalLightNode
  • Componente do Animador –> AnimationNode (e classes derivadas, veja abaixo)
  • Componente do Colisor de Caixas -> BoxGeometryNode
  • Componente colisor do Sphere -> SphereGeometryNode
  • Componente Capsule Collider -> CapsuleGeometryNode
  • Componente mesh Collider -> MeshGeometryNode
  • Componente Text Mesh Pro -> TextNode
  • Componente Rigidbody -> RigidBodyNode

Por exemplo, se criar uma cena com um objeto de jogo que tenha um componente Light (definido como uma luz de ponto) e um colisor de esferas ligado, a sua cena conterá um TransformNode com duas crianças: um PointLightNode e um SphereGeometryNode.

Além disso, alguns objetos da API de Scripting na Cloud do Mesh não têm componentes do Unity incorporados correspondentes. Estes são componentes adicionais que pode criar no Unity que fazem parte do pacote de toolkit do Mesh.

  • Componente de Scripting na Cloud do Mesh (descrito acima)
  • Componente WebSlate

Mapear o DOM do Unity para o DOM do Mesh

Pode criar uma cena com componentes que a API de Scripting na Cloud do Mesh não conhece. Estas simplesmente não existirão no DOM do Mesh Cloud Scripting para a cena. No entanto, a estrutura de cena completa dos GameObjects será espelhada na API DOM como TransformNodes.

O Unity tem uma forma de API GameObject/component; no entanto, o DOM do Mesh Cloud Scripting tem uma única estrutura de árvore. Um TransformNode na API de Scripting da Cloud do Mesh tem subordinados que podem ser outros TransformNodes ou podem ser outros Nós que mapeiam para componentes. Podemos considerar esta uma lista intercalada dos componentes do objeto de jogo associado e dos subordinados do componente de transformação.

Rect Transform

Se adicionar um componente que utiliza um RectTransform (por exemplo, o componente Text Mesh Pro), o objeto de jogo não será apresentado como um Nó no gráfico de cenas scripting da Cloud do Mesh. Ainda é possível mover, ativar e desativar esse componente, mas para tal, é necessário moldar o objeto de jogo utilizando RectTransform noutro objeto de jogo com o componente Transform normal.

Eventos de alteração de propriedade

Pode subscrever eventos de alteração de propriedade ao chamar AddPropertyChangedEventHandler qualquer nó na hierarquia. Tem de transmitir o nome da propriedade como uma cadeia.

Também é possível subscrever todos os eventos ao subscrever o DomObjectPropertyChanged evento. Isto é chamado quando qualquer propriedade no DOM é alterada.

Ciclo de vida do objeto

Os nós, quando criados, não estão preparados. Isto significa que não serão visíveis na cena até serem explicitamente adicionados como uma criança à cena ou a um dos seus descendentes. Da mesma forma, definir o elemento principal de um nó como nulo irá removê-lo e aos seus descendentes da cena.

Por vezes, quer desativar um nó temporariamente, mas não manter um registo de onde estava no local. Por este motivo, cada Nó tem um sinalizador "ativo". Quando definido como falso, desativará o nó e os respetivos descendentes.

Pode criar objetos de jogo e componentes no Unity que fazem parte da cena, mas que estão desativados. Estes serão apresentados como Nós na hierarquia de cenários do Mesh Cloud Scripting, mas terão o sinalizador ativo definido como falso. Definir o sinalizador ativo como verdadeiro irá ativá-los na cena do Unity.

Clonagem e reaparente

Os nós podem ser clonados e reparentedos na API de Scripting da Cloud do Mesh; a cena do Unity correspondente será atualizada em conformidade. Se clonar um nó, este clonará esse nó e todos os respetivos subordinados (incluindo crianças que podem estar nos objetos do Unity correspondentes, mas que não estão visíveis para o Mesh Cloud Scripting).

É possível clonar ou reparenter Nós que correspondam aos Componentes do Unity. Isto é implementado ao recriar estes componentes do Unity com base nas representações do Nó de Scripting da Cloud do Mesh. Apenas os Nós que podem ser criados através da API de Scripting na Cloud do Mesh podem ser clonados ou reparentedos. Se tiver criado um componente no Unity e definido campos que não se refletem no Nó de Script da Cloud do Mesh correspondente, estes campos serão repostos para as respetivas predefinições se o próprio Nó for clonado. Por este motivo, recomendamos que clone ou reapare os Nós de Transformação onde está a manipular objetos criados no Unity. Estes irão manter sempre corretamente todas as definições originais do Unity.

Utilizadores

Existem vários locais na API que fornecem propriedades de Utilizador. A User.Identifier propriedade é uma cadeia de identificador persistente que é persistente para o utilizador, mesmo que o utilizador saia e volte a participar. O nome a apresentar do utilizador também está acessível através de User.DisplayName. O ID do evento a partir do qual o utilizador se ligou está acessível através de User.ConnectedEventId.

Durante o desenvolvimento, o nome a apresentar do utilizador, o identificador e o ID do evento podem ser simulados no editor de componentes do Mesh Cloud Scripting nas "Definições do Programador", conforme mostrado abaixo.

Propriedades do Utilizador Simulado

Avatares

Os avatares são a representação dos utilizadores na cena. Podem ser utilizados para teletransportar utilizadores para uma determinada localização, viajar entre cenas e detetar colisões com volumes de acionadores.

Caixas de Diálogo de Informações

É possível no Mesh Cloud Scripting abrir uma caixa de diálogo de espaço no ecrã na aplicação Microsoft Mesh com uma mensagem personalizada. SceneNode contém uma função para isto, ShowMessageToParticipants(string message, IReadOnlyCollection<Participant> participants). As etiquetas de texto avançadas podem ser utilizadas na mensagem para controlar as propriedades do texto (cor, negrito, etc.).

Caixas de Diálogo de Entrada

O Mesh Cloud Scripting pode pedir entrada de texto a um participante num evento do Mesh com uma mensagem personalizada. CloudApplication fornece o método Task<string> ShowInputDialogToParticipantAsync(string message, Participant participant, CancellationToken token). As etiquetas de texto avançadas podem ser utilizadas na mensagem para controlar as propriedades do texto (por exemplo, cor ou negrito).

Classes

CloudApplication

A ICloudApplication interface é o ponto de partida para desenvolver aplicações do Mesh. Está disponível em "App.cs" como a variável _app. Além da cena, ICloudApplication tem funções de criação para todos os tipos disponíveis. Também tem vários outros métodos, mas são para utilização interna.

InteractableNode

O MeshInteractableSetup é um componente do Unity personalizado que faz parte do pacote de toolkit do Mesh. Ao anexá-lo a um objeto de jogo no Unity, este irá gerar eventos de clique quando qualquer utilizador clicar em qualquer um dos colidiveis ativos nesse objeto de jogo ou nos respetivos subordinados.

Um exemplo simples é apresentado abaixo, onde o componente MeshInteractableSetup é adicionado ao mesmo objeto de jogo que o colisor de caixa:

Exemplo de Entrada Simples

WebSlateNode

O WebSlate é um componente personalizado do Unity que faz parte do pacote de toolkit do Mesh. Para adicionar uma prefab WebSlate à sua cena, selecione GameObject>Mesh Toolkit>WebSlate na barra de menus. O site atribuído à propriedade URL da instância webSlate é composto no quad deste prefáb.

É apresentado um exemplo abaixo, em que foi adicionado um prefab WebSlate à cena e atribuído um Url:

        var webSlateNode = Root.FindFirstChild<WebSlateNode>(true);
        webSlateNode.Url = new System.Uri("https://en.wikipedia.org/wiki/Color");

Exemplo de webSlate

Escutar cliques

Segue-se um script de Scripts da Cloud do Mesh simples que roda o cubo sempre que é clicado. Substitua o método stub StartAsync no interior App.cs por este código.

        private float _angle = 0;

        public Task StartAsync(CancellationToken token)
        {
            // First we find the TransformNode that corresponds to our Cube gameobject
            var transform = _app.Scene.FindFirstChild<TransformNode>();

            // Then we find the InteractableNode child of that TransformNode
            var sensor = transform.FindFirstChild<InteractableNode>();

            // Handle a button click
            sensor.Selected += (_, _) =>
            {
                // Update the angle on each click
                _angle += MathF.PI / 8;
                transform.Rotation = new Rotation { X = 1, Y = 0, Z = 0, Angle = _angle };
            };

            return Task.CompletedTask;
        }

Informações de Acesso

É possível descobrir que utilizador clicou no colisor ao observar os argumentos do evento de alteração de propriedade. Também pode ler o contacto normal e a posição do clique a partir dos argumentos do evento. Estas coordenadas serão relativas ao espaço de coordenadas local do InteractableNode.

Animadores

Pode criar e adicionar um Animador do Unity à sua cena e controlá-lo através do Mesh Cloud Scripting. O plug-in do Toolkit do Mesh irá analisar os recursos no seu projeto do Unity e, para cada Animator encontrado, irá gerar uma classe numa pasta "AnimationScripts" no projeto Mesh Cloud Scripting. Esta classe deriva do AnimationNode e pode ser utilizada para controlar o Animator a partir do Mesh Cloud Scripting. Quando adiciona o Animator como um componente a um objeto de jogo no Unity, encontrará uma instância correspondente da classe gerada como subordinado do TransformNode correspondente. Com a API desta classe, pode controlar o Animator.

O modelo de programação mesh Cloud Scripting é autoritativo do servidor e suportamos apenas um pequeno subconjunto da funcionalidade Animator. Isto acontece porque modelamos o Animator no servidor e esperamos que todos os clientes sejam sincronizados com precisão com o modelo de servidor. Por este motivo, apenas a seguinte API é atualmente suportada:

  • Definição de estado (para cada camada existe uma propriedade correspondente na classe que pode ser definida como uma enumeração com base nos estados disponíveis no Animator). Os estados são definidos imediatamente, não através de transições.
  • Definição de variável flutuante: apenas as variáveis flutuantes são expostas e apenas para efeitos de enlace a "Tempo de Movimento" num Animator.
  • Definição de velocidade da camada

Num estado, pode criar um Clip de Animação sem restrições sobre os valores que pode definir na cena do Unity. Os Clips de Animação em Ciclo também são suportados. As seguintes funcionalidades dos Animadores não são suportadas através de AnimationNodes:

  • Transições: se adicionar transições ao seu Animator, não poderá acioná-las através da API de Scripting na Cloud do Mesh (o servidor não modela transições).
  • Variáveis (para além de flutuantes para conduzir o Tempo de movimento). As variáveis utilizadas para impulsionar a lógica de transição ou os multiplicadores de velocidade não são suportadas.
  • Estados espelhados, Deslocamento do ciclo e IK do pé.

Associação e Animadores Atrasados

Quando os clientes aderem a um Evento do Mesh, sincronizam com o estado atual e a hora local de todos os Nós de Animação em execução. Se tiver uma animação de execução prolongada a ser reproduzida num estado, o tempo de reprodução será definido para a hora atual correta da animação em associação tardia. No entanto, se o seu estado acionar eventos, estes NÃO serão acionados no cliente associado tardio. Alguns outros cenários podem não funcionar conforme esperado; por exemplo, se acionar um som ao ativar um AudioSource no início de um estado, esse AudioSource continuará ativado no cliente de associação tardia, mas começará a ser reproduzido no início do clip de áudio.

Estado inicial do animador

Recomendamos que crie Animadores com estados predefinidos que não fazem nada. Quando uma cena começa a ser reproduzida no Unity, ativa todos os Animadores e começa a reproduzir as suas animações predefinidas. Isto pode acontecer antes de ocorrer a ligação do Mesh Cloud Scripting Service; Portanto, não há forma de sincronizar estes estados e o comportamento pode não ser o pretendido.

Animator reparenting and cloning (Reparenter e clonagem do animator)

Não é possível criar AnimationNodes através da API de Scripting na Cloud do Mesh. A única forma de criar um AnimationNode é exportar uma cena do Unity que contenha um componente animator. Se tentar clonar ou voltar a preparar o AnimationNode, receberá um erro porque não existe forma de suportar esta ação. Ainda é possível clonar ou repará-lo do elemento principal do AnimationNode, uma vez que corresponde ao Objeto de Jogo do Unity que pode ser clonado e parentado.

Notas sobre o Código Gerado

O código gerado removerá espaços dos nomes dos Animadores, Camadas, Estados e Variáveis; por exemplo, o nome da variável "my var" torna-se "myVar" no código. Por este motivo, é possível criar Animadores que não geram código válido. Por exemplo, se tiver duas variáveis chamadas "my var" e "myVar", receberá um erro durante a geração e uma mensagem a pedir-lhe para mudar o nome das variáveis.

LightNode

PointLightNode, DirectionalLightNode e SpotLightNode mapeiam todos para o componente Unity Light (que terá o tipo definido para o valor correspondente). É possível definir os parâmetros básicos destas luzes através das APIs LightNode. Também é possível criar luzes manualmente através da API. A criação de nós claros através da API irá deixar os parâmetros que não estão definidos através da API de Scripting na Cloud de Mesh para as respetivas predefinições.

GeometryNode

BoxGeometryNode, SphereGeometryNode, CapsuleGeometryNode e MeshGeometryNode mapeiam para o Componente Colisor de Caixas do Unity, Componente de Colisor do Sphere, Componente de Colisor de Cápsulas e Componente de Colisor de Malha, respetivamente. Também podem ser criados através da API de Scripting na Cloud do Mesh. Ativar e desativar os Nós de Geometria irá adicioná-los e removê-los dos candidatos de acesso se um MeshInteractableSetup estiver anexado ao objeto de jogo ou a um dos respetivos pais.

A criação de nós de geometria através da API deixará os parâmetros que não estão definidos através da API de Malha para as respetivas predefinições (por exemplo, Material físico será definido como nenhum e isTrigger será definido como falso).

RigidBodyNode

Adicionar um componente Rigidbody a um objeto colocará o seu movimento sob o controlo da Física de Malha. Sem adicionar qualquer código, um objeto Rigidbody será puxado para baixo pela gravidade e reagirá a colisões com outros objetos.

Nota: GeometryNode.Friction irá devolver staticFriction. No entanto, se estiver definido no lado do Mesh Cloud Scripting, irá atualizar tanto nos dynamicFriction clientes como staticFriction nos clientes.

Volumes de acionador

Os nós de geometria podem agir como volumes de acionador quando a respetiva IsTrigger propriedade está definida como verdadeira. Este sinalizador corresponde à IsTrigger propriedade no colisor no Unity e não pode ser alterado no runtime. Quando a geometria é um acionador, irá gerar Entered e Exited para quaisquer Avatares que comecem/parem de se sobrepor ao mesmo.

Nota: o objeto Unity tem de ser adicionado à TriggerVolume camada para permitir que o feixe de teletransporte o ignore, uma vez que os Default colisores na camada bloqueiam o feixe de teletransporte.

TextNode

O TextNode mapeia para o componente TextMeshPro do Unity. Se adicionar um componente TextMeshPro à sua cena, existirá um TextNode correspondente na hierarquia de cenas de Scripting na Cloud do Mesh. Isto permite-lhe definir o texto do componente no runtime. Também pode alterar as propriedades básicas do texto através da API textNode – negrito, itálico, sublinhado, rasurado e cor. Atualmente, não é possível criar um TextNode através da API; tem de criá-las ao adicioná-las à sua cena no Unity. Além disso, não pode clonar um TextNode diretamente. Em vez disso, tem de clonar o TranformNode principal do TextNode.

Malhas

As malhas são atualmente componentes "ocultos" para a API de Scripting na Cloud do Mesh. Podem ser criados no editor do Unity e podem ser manipulados manipulando os respetivos objetos de jogo principais/Transformar componentes, mas não podem ser criados programaticamente, nem as respetivas propriedades podem ser editadas no runtime através da API de Mesh.

Outros tópicos de Scripting na Cloud do Mesh

Adicionar recursos ao Mesh Cloud Scripting Service

Se precisar de adicionar um recurso para utilizar o Mesh Cloud Scripting Service, tem de o adicionar como um recurso incorporado ao ficheiro de projeto C#. Isto pode ser feito através da IU do projeto no Visual Studio ou ao adicionar diretamente a seguinte linha ao ficheiro .csproj:

<EmbeddedResource Include="<my_resource_file>" CopyToOutputDirectory="PreserveNewest" />

Tenha em atenção que é assim que o scene.map é empacotado, que pode ver no ficheiro .csproj para referência.

Trabalhar com a Física do Mesh

Mesh Physics terá o cuidado de sincronizar o movimento de corpos rígidos entre clientes. Mesh Cloud Scripting TransformNode.Position, TransformNode.RotationRigidBody.Velocity e RigidBody.AngularVelocity não será atualizado com o estado de simulação mais recente. No entanto, os clientes aplicarão alterações se estas estiverem definidas no Mesh Cloud Scripting Service. Tenha em atenção que a alteração da propriedade individual deixará outras pessoas inalteradas. Por exemplo, se apenas a posição estiver definida, a velocidade não será alterada e o corpo rígido continuará o movimento com velocidade antiga da nova posição. Dado que o Mesh Cloud Scripting Service não é atualizado com o estado de movimento mais recente para corpos rígidos, a recomendação é defini-los apenas para novos corpos rígidos.

Se TransformNode for RigidBodyNode clonado, o corpo clonado será registado e entregue para Mesh Physics sincronização entre clientes. Nota: o corpo rígido clonado terá posição, rotação e velocidades desde o início da cena do corpo rígido original. Se estas devem ser diferentes, têm de ser definidas explicitamente no Mesh Cloud Scripting.

Passos seguintes