Animaciones de modelos 3D
Cómo animar modelos 3D en tu scene
Modelos 3D en .glTF y .glb pueden incluir tantas animaciones como quieras. Las animaciones le indican a la malla cómo moverse, especificando una serie de keyframes que se distribuyen en el tiempo; luego, la malla transita de una pose a otra para simular un movimiento continuo.
La mayoría de las animaciones de modelos 3D son animaciones esqueléticas. Estas animaciones simplifican la compleja geometría del modelo a una "figura de palo", vinculando cada vértice de la malla al bone más cercano en el skeleton. Los modeladores ajustan el skeleton en distintas poses, y la malla se estira y se dobla para seguir esos movimientos.
Como alternativa, las animaciones de vértices animan un modelo sin necesidad de un skeleton. Estas animaciones especifican directamente la posición de cada vértice del modelo. Decentraland también admite estas animaciones.
Consulta Animations para obtener detalles sobre cómo crear animaciones para un modelo 3D. Lee Shape components para instrucciones sobre cómo importar un modelo 3D a una escena.
💡 Consejo: Las animaciones suelen ser mejores para mover algo en su lugar, no para cambiar la posición de una Entity. Por ejemplo, puedes configurar una animación para mover los pies de un personaje en el sitio, pero para cambiar la ubicación de la Entity es mejor usar el componente Transform. Consulta Posicionamiento de entities para más detalles.
Comprueba un modelo 3D para ver si tiene animaciones
No todos los glTF files incluyen animaciones. Para ver si hay alguna disponible, puedes hacer lo siguiente:
Si usas VS Code(recomendado), instala la extensión GLTF Tools y visualiza allí el contenido de un archivo glTF.
Abre el Babylon Sandbox sitio y arrastra el archivo glTF (y cualquier dependencia .jpg o .bin ) al navegador.
Abre el .glTF file con un editor de texto y desplázate hacia abajo hasta encontrar "animations":.
💡 Consejo: En las animaciones esqueléticas , el nombre de una animación suele estar compuesto por el nombre de su armature, un guion bajo y el nombre de su animación. Por ejemplo myArmature_animation1.
Reproducción automática
Si un modelo 3D incluye alguna animación, el comportamiento predeterminado es que la primera de ellas siempre se reproduce en bucle.
Para evitar este comportamiento, añade un Animator componente a la Entity que tiene el modelo, y luego gestiona explícitamente la reproducción de las animaciones. Si un Animator componente está presente en la Entity, todas las animaciones tienen por defecto un estado playing: false y deben reproducirse manualmente.
💡 Consejo: En el Scene Editor, puedes añadir un Animator componente visualmente. Consulta Add Components. También puedes controlar las animaciones sin código mediante Actions, ver Haz que cualquier item sea smart.
Gestionar las animaciones explícitamente
Un Animator El componente se usa para acceder a todas las animaciones de la Entity y puede usarse para indicar explícitamente a la Entity que reproduzca o detenga una animación. El Animator componente incluye un array de states, esta lista debe incluir un objeto por cada una de las animaciones que el modelo 3D puede realizar. Un solo Animator puede incluir tantos states como sea necesario.
Cada state objeto lleva un seguimiento de si una animación se está reproduciendo actualmente.
📔 Nota: La Animator component debe importarse mediante
import { Animator } from "@dcl/sdk/ecs"
Consulta Imports para ver cómo manejar esto fácilmente.
Obtener una animación
Obtén un clip del Animator por nombre usando la función .Animator.getClip(). Esta función devuelve una versión mutable del objeto de estado de la animación.
Animator.getClip requiere los siguientes parámetros:
entity: La Entity delAnimatorcomponente que quieres consultar.clipName: Cadena con el nombre del clip que quieres obtener.
Animator.getClip obtiene una versión mutable del estado de la animación, para que puedas modificar libremente los valores sobre lo que devuelve esta función.
📔 Nota: Si intentas usar Animator.getClip() para obtener un clip que existe en el modelo 3D, pero no está listado en el Animator componente, devuelve null.
Reproducir una animación
El .playing campo en un estado de animación determina si la animación se está reproduciendo actualmente. Ten en cuenta que varias animaciones pueden estar reproduciéndose en un mismo modelo 3D al mismo tiempo.
Usa la Animator.playSingleAnimation() función en un objeto AnimationState .
Si la Entity estaba reproduciendo otras animaciones, Animator.playSingleAnimation las detiene.
Animator.playSingleAnimation requiere los siguientes parámetros:
entity: La Entity delAnimatorcomponente que quieres afectar.clipName: Cadena con el nombre del clip que quieres reproducir.resetCursor: (opcional) Si true, reproduce la animación desde el inicio, incluso si la animación estaba pausada anteriormente. Si false, seguirá reproduciendo la animación desde donde se pausó. Predeterminado: true.
La siguiente tabla resume cómo Animator.playSingleAnimation() se comporta, usando distintos valores para la propiedad resetCursor :
reset = false (predeterminado)
reset = true
Reproduciéndose actualmente
No tiene efecto.
Reproduce desde el inicio.
Pausada
Se reanuda desde el último frame reproducido.
Reproduce desde el inicio.
Terminado (sin bucle)
Reproduce desde el inicio.
Reproduce desde el inicio.
Animaciones en bucle
De forma predeterminada, las animaciones se reproducen en un bucle que repite la animación para siempre.
Cambia esta configuración estableciendo la loop propiedad en el state .
Si looping se establece en false, la animación se reproduce solo una vez y luego se detiene, permaneciendo en la postura del último frame.
Detener una animación
Para detener todas las animaciones que una Entity está reproduciendo, usa Animator.stopAllAnimations().
Animator.stopAllAnimations requiere los siguientes parámetros:
entity: La Entity delAnimatorcomponente que quieres afectar.resetCursor: (opcional) Si true, vuelve a la postura del primer frame de la animación. Si false, permanece en pausa en su postura actual. Predeterminado: true.
📔 Nota: Al reproducir una animación con Animator.playSingleAnimation, esta función se encarga de detener todas las demás animaciones internamente. En ese caso, no necesitas detener explícitamente las otras animaciones.
Cuando una animación termina de reproducir una animación sin bucle, de forma predeterminada el modelo 3D permanece en la última postura que tenía. Para cambiar este comportamiento predeterminado de modo que, cuando la animación termine, vuelva a la primera postura, establece el shouldReset propiedad en true.
También puedes usar Animator.stopAllAnimations() en cualquier momento para restablecer explícitamente la postura al primer frame de la animación.
📔 Nota: Restablecer la postura es un cambio abrupto. Si quieres hacer que el modelo transicione suavemente a otra postura, puedes hacer cualquiera de estas dos cosas:
Gestionar múltiples animaciones
Si un modelo 3D tiene varias animaciones empaquetadas en él, un solo Animator componente puede encargarse de todas ellas.
En el ejemplo anterior, dos animaciones se gestionan mediante state objetos separados, y luego ambos se asignan al mismo Animator componente.
Cada bone de una animación solo puede verse afectado por una animación a la vez, a menos que esas animaciones tengan un weight que sume un valor de 1 o menos.
Si una animación solo afecta a las piernas de un personaje, y otra solo afecta a la cabeza de un personaje, entonces pueden reproducirse al mismo tiempo sin problema. Pero si ambas afectan a las piernas del personaje, entonces debes reproducir solo una a la vez o reproducirlas con valores de weight más bajos.
Si en el ejemplo anterior, la animación bite solo afecta a la boca del shark, y la animación swim solo afecta a los bones de la columna vertebral del shark, entonces ambas pueden reproducirse al mismo tiempo si están en layers separadas.
📔 Nota: Animator.playSingleAnim() detiene todas las demás animaciones que la Entity esté reproduciendo actualmente. Para reproducir varias animaciones al mismo tiempo, modifica manualmente la propiedad playing en los estados de animación.
Velocidad de la animación
Cambia la velocidad a la que se reproduce una animación cambiando la propiedad speed . El valor de speed es 1 por defecto.
Establece la velocidad por debajo de 1 para reproducirla más lento, por ejemplo 0.5 para reproducirla a la mitad de velocidad. Establécela por encima de 1 para reproducirla más rápido, por ejemplo 2 para reproducirla al doble de velocidad.
Peso de la animación
El weight La propiedad permite que un solo modelo realice varias animaciones en diferentes layers al mismo tiempo, calculando un promedio ponderado de todos los movimientos involucrados en la animación. El valor de weight determina cuánta importancia se le dará a esa animación en el promedio.
De forma predeterminada, weight es igual a 1. El valor de weight no puede ser mayor que 1.
El weight de los valores de todas las animaciones activas en una Entity debe sumar 1 en todo momento. Si suma menos de 1, el promedio ponderado usará la posición predeterminada del armature para la parte restante del cálculo.
Por ejemplo, en el ejemplo de código anterior, estamos reproduciendo la animación swim que solo tiene un weight de 0.2. Este movimiento de natación será bastante sutil: solo el 20% de la intensidad que define la animación. El 80% restante del cálculo toma valores de la postura predeterminada del armature.
El weight La propiedad puede usarse de formas interesantes; por ejemplo, la propiedad weight propiedad de swim podría establecerse en proporción a la rapidez con la que el shark está nadando, de modo que no necesites crear varias animaciones para nadar rápido y despacio.
También podrías cambiar el valor de weight gradualmente al iniciar y detener una animación para darle una transición más natural y evitar saltos desde la pose predeterminada hasta la primera pose de la animación.
📔 Nota: El valor añadido de weight de todas las animaciones que actúan sobre un bone de un modelo 3D no puede ser superior a 1. Si más de una animación está afectando a los mismos bones al mismo tiempo, deben tener su weight configurado con valores que sumen menos de 1.
Última actualización