Guía del programador de Scripting en la nube
En esta guía se describe cómo usar mesh Cloud Scripting API y las herramientas de desarrollo para compilar entornos (estos comienzan como proyectos en Unity y, a continuación, se cargan en una colección mesh). Se recomienda leer primero la infraestructura Set cloud Scripting in Azure (Establecer la infraestructura de scripting en la nube en Azure ) para familiarizarse con los conceptos y la arquitectura básica de Mesh Cloud Scripting.
En esta sección se describen las características y la interfaz de mesh Cloud Scripting API, que se usa para escribir los scripts que impulsan comportamientos en entornos.
Estructura DOM básica
La estructura DOM refleja la estructura de la escena de Unity. El miembro "Scene" de la aplicación corresponde al objeto de juego al que está asociado el componente Mesh Cloud Scripting. Las siguientes clases mesh Cloud Scripting API asignan uno a uno con objetos de Unity creados en el editor:
- GameObject (& Transformar componente) -> TransformNode
- Componente de luz:> PointLightNode, SpotLightNode, DirectionalLightNode
- Componente de animador:> AnimationNode (y clases derivadas, consulte a continuación)
- Componente de colisionador de cuadros:> BoxGeometryNode
- Componente De colisionador de esfera:> SphereGeometryNode
- Componente del colisionador de cápsula -> CapsuleGeometryNode
- Componente del colisionador de malla:> MeshGeometryNode
- Componente Text Mesh Pro:> TextNode
- Componente Rigidbody -> RigidBodyNode
Por ejemplo, si crea una escena con un objeto de juego que tiene un componente Light (establecido en una luz puntual) y un colisionador de esfera conectado, la escena contendrá un TransformNode con dos elementos secundarios: PointLightNode y SphereGeometryNode.
Además, algunos objetos mesh Cloud Scripting API no tienen componentes integrados de Unity correspondientes. Estos son componentes adicionales que puede crear en Unity que forman parte del paquete del kit de herramientas de Mesh.
- Componente Mesh Cloud Scripting (descrito anteriormente)
- Componente WebSlate
Asignación del DOM de Unity al DOM de malla
Puede crear una escena con componentes que mesh Cloud Scripting API no conoce. Esto simplemente no existirá en mesh Cloud Scripting DOM para la escena. Sin embargo, la estructura de escena completa de GameObjects se reflejará en la API DOM como TransformNodes.
Unity tiene una forma de API GameObject/component; sin embargo, mesh Cloud Scripting DOM tiene una única estructura de árbol. Un TransformNode en mesh Cloud Scripting API tiene elementos secundarios que pueden ser otros TransformNodes o pueden ser otros nodos que se asignan a componentes. Podemos considerar esta lista combinada de los componentes del objeto de juego asociado y los elementos secundarios de su componente de transformación.
Rect Transform
Si agregas un componente que usa rectTransform (por ejemplo, el componente Text Mesh Pro), el objeto de juego no aparecerá como un nodo en el gráfico de escena Mesh Cloud Scripting. Todavía es posible mover, habilitar y deshabilitar este componente, pero para ello, es necesario encapsular el objeto de juego mediante RectTransform en otro objeto de juego mediante el componente transformación normal.
Eventos de cambio de propiedades
Puede suscribirse a eventos de cambio de propiedad llamando a AddPropertyChangedEventHandler
en cualquier nodo de la jerarquía. Debe pasar el nombre de la propiedad como una cadena.
También es posible suscribirse a todos los eventos mediante la suscripción al DomObjectPropertyChanged
evento. Esto se llama cuando cambia cualquier propiedad del DOM.
Ciclo de vida de objetos
Los nodos, cuando se crean, no son primarios. Esto significa que no estarán visibles en la escena hasta que se agreguen explícitamente como elemento secundario a la escena o a uno de sus descendientes. Del mismo modo, establecer el elemento primario de un nodo en NULL lo quitará y sus descendientes de la escena.
A veces quiere deshabilitar un nodo temporalmente, pero no mantener un registro de dónde estaba en la escena. Por este motivo, cada nodo tiene una marca "activa". Cuando se establece en false, deshabilitará el nodo y sus descendientes.
Puedes crear componentes y objetos de juego en Unity que forman parte de la escena, pero que están deshabilitados. Estos aparecerán como Nodos en la jerarquía de la escena mesh Cloud Scripting, pero tendrán su marca activa establecida en false. Si se establece la marca activa en true, se habilitarán en la escena de Unity.
Clonación y reparentación
Los nodos se pueden clonar y reparentar en mesh Cloud Scripting API; la escena de Unity correspondiente se actualizará según corresponda. Si clona un nodo, clonará ese nodo y todos sus elementos secundarios (incluidos los elementos secundarios que pueden estar en los objetos de Unity correspondientes, pero no son visibles para Mesh Cloud Scripting).
Es posible clonar o reparentar nodos que corresponden a componentes de Unity. Esto se implementa mediante la recreación de estos componentes de Unity en función de las representaciones del nodo de scripting en la nube de Mesh. Solo se pueden clonar o volver a crear nodos que se pueden crear a través de mesh Cloud Scripting API. Si ha creado un componente en Unity y ha establecido campos que no se reflejan en el nodo de scripting en la nube de malla correspondiente, estos campos se restablecerán a sus valores predeterminados si se clona el propio nodo. Por este motivo, se recomienda clonar o volver a crear nodos de transformación primarios en los que se manipulan objetos creados en Unity. Estos siempre mantendrán correctamente toda la configuración original de Unity.
Usuarios
Hay varios lugares en la API que proporcionan propiedades de usuario. La User.Identifier
propiedad es una cadena de identificador persistente que es persistente para el usuario, incluso si el usuario deja y vuelve a unirse. El nombre para mostrar del usuario también es accesible a través User.DisplayName
de . El identificador de evento desde el que se ha conectado el usuario es accesible a través User.ConnectedEventId
de .
Durante el desarrollo, el nombre para mostrar del usuario, el identificador y el identificador de evento se pueden simular en el editor de componentes Mesh Cloud Scripting en la "Configuración del desarrollador", como se muestra a continuación.
Avatares
Los avatares son la representación de los usuarios en la escena. Se pueden usar para teletransportar a los usuarios a una ubicación determinada, viajar entre escenas y detectar colisiones con volúmenes desencadenadores.
Cuadros de diálogo de información
Es posible que en Mesh Cloud Scripting aparezca un cuadro de diálogo de espacio de pantalla en la aplicación Microsoft Mesh con un mensaje personalizado. SceneNode contiene una función para esto, ShowMessageToParticipants(string message, IReadOnlyCollection<Participant> participants)
. Las etiquetas de texto enriquecido se pueden usar en el mensaje para controlar las propiedades de texto (color, negrita, etc.).
Cuadros de diálogo de entrada
Mesh Cloud Scripting puede solicitar una entrada de texto de un asistente en un evento Mesh con un mensaje personalizado. CloudApplication
proporciona el método Task<string> ShowInputDialogToParticipantAsync(string message, Participant participant, CancellationToken token)
. Las etiquetas de texto enriquecido se pueden usar en el mensaje para controlar las propiedades de texto (por ejemplo, color o negrita).
Clases
CloudApplication
La ICloudApplication
interfaz es el punto de partida para desarrollar aplicaciones mesh. Está disponible en "App.cs" como la variable _app. Además de la escena, ICloudApplication
tiene funciones de creación para todos los tipos disponibles. También tiene una serie de otros métodos, pero son para uso interno.
InteractableNode
MeshInteractableSetup es un componente de Unity personalizado que forma parte del paquete del kit de herramientas de Mesh. Al adjuntarlo a un objeto de juego en Unity, generará eventos de clic cuando cualquier usuario haga clic en cualquiera de los collidables activos de ese objeto de juego o sus elementos secundarios.
A continuación se muestra un ejemplo sencillo, donde el componente MeshInteractableSetup se agrega al mismo objeto de juego que el colisionador de cuadros:
WebSlateNode
WebSlate es un componente de Unity personalizado que forma parte del paquete del kit de herramientas mesh. Para agregar un objeto prefabricado WebSlate a la escena, seleccione GameObject>Mesh Toolkit>WebSlate en la barra de menús. El sitio web asignado a la propiedad URL de la instancia de WebSlate se representa en el quad de este objeto prefabricado.
A continuación se muestra un ejemplo, donde se ha agregado un objeto prefabricado WebSlate a la escena y se le ha asignado una dirección URL:
var webSlateNode = Root.FindFirstChild<WebSlateNode>(true);
webSlateNode.Url = new System.Uri("https://en.wikipedia.org/wiki/Color");
Escucha de clics
Este es un script simple de Scripting en la nube mesh que gira el cubo cada vez que se hace clic en él. Reemplace el método de código auxiliar StartAsync
dentro 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;
}
Información de aciertos
Es posible averiguar qué usuario ha hecho clic en el colisionador examinando los argumentos del evento de cambio de propiedad. También puede leer el contacto normal y la posición del clic desde los argumentos del evento. Estas coordenadas serán relativas al espacio de coordenadas local del InteractableNode.
Animadores
Puede crear y agregar un animador de Unity a la escena y controlarlo a través de Mesh Cloud Scripting. El complemento mesh toolkit examinará los recursos del proyecto de Unity y, para cada animador que se encuentra, generará una clase en una carpeta "AnimationScripts" en el proyecto Mesh Cloud Scripting. Esta clase se deriva de AnimationNode y se puede usar para controlar el Animator de Mesh Cloud Scripting. Al agregar el Animator como componente a un objeto de juego en Unity, encontrará una instancia correspondiente de la clase generada como elemento secundario del objeto TransformNode correspondiente. Con la API de esta clase, puede controlar el Animator.
El modelo de programación Mesh Cloud Scripting es autoritativo del servidor y solo se admite un pequeño subconjunto de la funcionalidad animator. Esto se debe a que modelamos el animador en el servidor y esperamos que todos los clientes se sincronicen con precisión con el modelo de servidor. Por este motivo, solo se admite actualmente la SIGUIENTE API:
- Configuración de estado (para cada capa hay una propiedad correspondiente en la clase que se puede establecer en una enumeración basada en los estados disponibles en el Animator). Los estados se establecen inmediatamente, no a través de transiciones.
- Valor de variable float: solo se exponen variables float y solo para enlazar a "Tiempo de movimiento" en un Animator.
- Configuración de velocidad de capa
Dentro de un estado, puede crear un clip de animación sin restricciones sobre los valores que puede establecer en la escena de Unity. También se admiten clips de animación de bucle. Las siguientes características de Animators no se admiten a través de AnimationNodes:
- Transiciones: si agrega transiciones al animador, no podrá desencadenarlas a través de mesh Cloud Scripting API (el servidor no modela las transiciones).
- Variables (distintas de floats para impulsar el tiempo de movimiento). No se admiten las variables usadas para impulsar la lógica de transición o los multiplicadores de velocidad.
- Estados reflejados, desplazamiento del ciclo y IK de pie.
Unión tardía y animadores
Cuando los clientes se unen a un evento mesh, se sincronizan con el estado actual y la hora local de todos los nodos de animación en ejecución. Si tienes una animación de larga duración reproduciendo en un estado, la hora de reproducción se establecerá en la hora actual correcta de la animación en combinación tardía. Sin embargo, si el estado desencadena eventos, estos no se desencadenarán en el cliente unido tarde. Es posible que otros escenarios no funcionen según lo previsto; Por ejemplo, si desencadena un sonido habilitando audioSource al principio de un estado, audioSource seguirá estando habilitado en el cliente de unión tardía, pero comenzará a reproducirse al principio del clip de audio.
Estado inicial del animador
Se recomienda crear animadores que tengan estados predeterminados que no hagan nada. Cuando una escena comienza a reproducirse en Unity, activará todos los animadores y empezará a reproducir sus animaciones predeterminadas. Esto puede ocurrir antes de que se produzca la conexión de Mesh Cloud Scripting Service; por lo tanto, es posible que no haya ninguna manera de sincronizar estos estados y comportamiento.
Reparenting y clonación del animador
AnimationNodes no se puede crear a través de Mesh Cloud Scripting API. La única manera de crear un AnimationNode es exportando una escena de Unity que contiene un componente Animator. Si intenta clonar o reparentar AnimationNode, obtendrá un error porque no hay ninguna manera de admitir esta acción. Todavía es posible clonar o reparentar el elemento primario del AnimationNode, ya que esto corresponde al objeto de juego de Unity que se puede clonar y primario.
Notas sobre el código generado
El código generado quitará espacios de nombres de animadores, capas, estados y variables; Por ejemplo, el nombre de variable "my var" se convierte en "myVar" en el código. Por este motivo, es posible crear animadores que no generen código válido. Por ejemplo, si tiene dos variables denominadas "my var" y "myVar", obtendrá un error durante la generación y un mensaje que le pide que cambie el nombre de las variables.
LightNode
PointLightNode, DirectionalLightNode y SpotLightNode se asignan al componente Light de Unity (que tendrá su tipo establecido en el valor correspondiente). Es posible establecer los parámetros básicos de estas luces a través de las API de LightNode. También es posible crear luces a través de la API. La creación de nodos ligeros a través de la API dejará los parámetros que no se pueden establecer a través de Mesh Cloud Scripting API a sus valores predeterminados.
GeometryNode
BoxGeometryNode, SphereGeometryNode, CapsuleGeometryNode y MeshGeometryNode se asignan al componente colisionador de cuadros de Unity, componente de colisionador de esfera, componente de colisionador de cápsulas y componente de colisión de malla, respectivamente. También se pueden crear a través de mesh Cloud Scripting API. Al habilitar y deshabilitar nodos de geometría, se agregarán y se quitarán de los candidatos de posicionamiento si meshInteractableSetup está asociado a su objeto de juego o a uno de sus elementos primarios.
La creación de nodos de geometría a través de la API dejará los parámetros que no se pueden establecer a través de Mesh API en sus valores predeterminados (por ejemplo, El material físico se establecerá en ninguno y isTrigger se establecerá en false).
RigidBodyNode
Agregar un componente Rigidbody a un objeto pondrá su movimiento bajo el control de la física de malla. Sin agregar ningún código, un objeto Rigidbody se extraerá hacia abajo por gravedad y reaccionará a colisiones con otros objetos.
Nota: GeometryNode.Friction
devolverá staticFriction
. Sin embargo, si se establece en mesh Cloud Scripting, se actualizará tanto como staticFriction
dynamicFriction
en los clientes.
Desencadenar volúmenes
Los nodos de geometría pueden actuar como volúmenes desencadenadores cuando su IsTrigger
propiedad se establece en true. Esta marca corresponde a la IsTrigger
propiedad del colisionador en Unity y no se puede cambiar en tiempo de ejecución. Cuando la geometría es un desencadenador, generará y Exited
para los Avatares que inicien o detengan Entered
la superposición con él.
Nota: El objeto Unity debe agregarse a la TriggerVolume
capa para permitir que el haz de teletransporte lo ignore, ya que los colisionadores de la Default
capa bloquean el haz de teletransporte.
TextNode
TextNode se asigna al componente TextMeshPro de Unity. Si agrega un componente TextMeshPro a la escena, habrá un TextNode correspondiente en la jerarquía de la escena de scripting en la nube de Mesh. Esto le permite establecer el texto del componente en tiempo de ejecución. También puede cambiar las propiedades de texto básicas a través de TextNode API: negrita, cursiva, subrayado, tachado y color. Actualmente no es posible crear un TextNode a través de la API; Debe crearlas agregando a la escena en Unity. Además, no puede clonar un TextNode directamente; en su lugar, debe clonar el TranformNode primario de TextNode.
Mallas
Las mallas están actualmente componentes "ocultos" en mesh Cloud Scripting API. Se pueden crear en el editor de Unity y se pueden manipular manipulando sus objetos de juego primarios o componentes de transformación, pero no se pueden crear mediante programación, ni sus propiedades se pueden editar en tiempo de ejecución a través de mesh API.
Scripts visuales
Puede crear y agregar una máquina de script de Unity a la escena y controlarla a través de Mesh Cloud Scripting. El complemento mesh toolkit examinará los recursos del proyecto de Unity y, para cada máquina de script que se encuentra, generará una clase en una carpeta "VisualScripts" en el proyecto Mesh Cloud Scripting. Esta clase deriva de VisualScriptNode y se puede usar para manipular las variables de Unity asociadas a script Machine desde Mesh Cloud Scripting. Al agregar script Machine como componente a GameObject en Unity, encontrará una instancia correspondiente de la clase generada como elemento secundario del objeto TransformNode correspondiente. Con la API de esta clase, puede controlar las variables de la máquina de scripts.
Sincronización de estado
De forma predeterminada, Mesh replica automáticamente los cambios de escena realizados por scripts visuales en un cliente en todos los demás clientes. Para que Mesh Cloud Scripting tenga en cuenta un cambio realizado a través del scripting visual, se deben cumplir las siguientes condiciones previas:
- El componente Script Machine está en un GameObject que es descendiente de la raíz de la escena mesh Cloud Scripting.
- La opción "Habilitar scripting visual" del componente Mesh Cloud Scripting está habilitada.
Si no se cumple alguna de las condiciones anteriores, el entorno de ejecución de Scripting visual mesh seguirá replicando los cambios en la escena, pero Mesh Cloud Scripting seguirá siendo ajeno a estos cambios.
Estado inicial
Se recomienda que los scripts visuales no modifiquen ni confíen en el estado compartido al iniciarse. Normalmente, el evento On Start se produce antes de que se produzca la conexión de Mesh Cloud Scripting Service; por lo tanto, no hay ninguna manera de sincronizar el estado en ese momento y el comportamiento puede no ser lo que desee.
Unión tardía
Cuando los clientes se unen a un evento mesh, se sincronizan con el estado actual de todos los nodos de script visual. Cualquier evento State Changed que se haya generado anteriormente en los demás clientes no se generará en el cliente unido tarde. Es posible que otros escenarios no funcionen según lo previsto; Por ejemplo, si desencadena un sonido habilitando audioSource en respuesta a un evento On State Changed, ese audioSource seguirá habilitado en el cliente de unión tardía, pero comenzará a reproducirse al principio del clip de audio.
Reparenting and clone (Reparenting and clone)
VisualScriptNode no se puede crear a través de mesh Cloud Scripting API. La única manera de crear un VisualScriptNode es exportar una escena de Unity que contenga un componente script Machine. Si intenta clonar o reparentar visualScriptNode, recibirá un error porque no hay ninguna manera de admitir esta acción. Todavía es posible clonar o reparentar el elemento primario del VisualScriptNode, ya que esto corresponde a la clase GameObject de Unity que se puede clonar y primario.
Notas sobre el código generado
El código generado quitará los espacios de los nombres de las variables y máquinas de script; por ejemplo, el nombre de variable "my var" se convierte en "MyVar" en el código. Por este motivo, es posible crear máquinas de script que no generen código válido. Por ejemplo, si tiene dos variables denominadas "my var" y "myVar", obtendrá un error durante la generación y un mensaje que le pide que cambie el nombre de las variables.
Otros temas de Scripting en la nube de Mesh
Adición de recursos al servicio Mesh Cloud Scripting
Si necesita agregar un recurso para que use Mesh Cloud Scripting Service, debe agregarlo como un recurso incrustado en el archivo de proyecto de C#. Esto se puede hacer a través de la interfaz de usuario del proyecto en Visual Studio o agregando la siguiente línea al archivo .csproj directamente:
<EmbeddedResource Include="<my_resource_file>" CopyToOutputDirectory="PreserveNewest" />
Tenga en cuenta que así es como se empaqueta scene.map, que puede ver en el archivo .csproj como referencia.
Trabajar con la física de malla
Mesh Physics
se encargará de sincronizar el movimiento de los cuerpos rígidos entre los clientes. Mesh Cloud Scripting TransformNode.Position
, TransformNode.Rotation
RigidBody.Velocity
y RigidBody.AngularVelocity
no se actualizarán con el estado de simulación más reciente. Sin embargo, los clientes aplicarán cambios si se establecen en Mesh Cloud Scripting Service. Tenga en cuenta que cambiar la propiedad única dejará otros sin cambios. Por ejemplo, si solo se establece la posición, la velocidad no se cambiará y el cuerpo rígido continuará el movimiento con la velocidad antigua desde la nueva posición. Dado que Mesh Cloud Scripting Service no se actualiza con el estado de movimiento más reciente para cuerpos rígidos, se recomienda establecer estos solo para nuevos cuerpos rígidos.
Si TransformNode
con RigidBodyNode
se clona, se registrará el cuerpo clonado y se entregará a Mesh Physics
para la sincronización entre clientes. Nota: El cuerpo rígido clonado tendrá posición, rotación y velocidades desde el principio de la escena del cuerpo rígido original. Si deben ser diferentes, deben establecerse explícitamente en Mesh Cloud Scripting.