Una criatura casi nunca reproduce una sola animación. Nuestro gólem de rubí debería quedarse quieto balanceándose, caminar cuando se mueve y levantar los puños cuando ve a un enemigo. Un controlador de animación decide cuál de ellas se reproduce en cada momento.
Esta guía parte de Animaciones de entidades. Léela primero si todavía no has hecho ninguna animación.
Los archivos
RP/
animations/
ruby_golem.animation.json
animation_controllers/
ruby_golem.animation_controllers.json
entity/
ruby_golem.entity.jsonPiensa en él como un conjunto de habitaciones
Un controlador es un conjunto de estados. Imagina cada estado como una habitación:
- La criatura siempre está en una sola habitación.
- Cada habitación tiene una lista de animaciones que se reproducen mientras la criatura está dentro.
- Cada habitación tiene puertas (transiciones). Cada puerta tiene una comprobación de Molang. Cuando la comprobación es verdadera, la criatura pasa a la otra habitación.
Para empezar, nuestro gólem tiene dos habitaciones: idle y walking.
Paso 1: quieto y caminando
Los archivos de controladores van en la carpeta animation_controllers del paquete de recursos:
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.ruby_golem.move": {
"initial_state": "idle",
"states": {
"idle": {
"animations": ["idle"],
"transitions": [
{ "walking": "query.modified_move_speed > 0.1" }
],
"blend_transition": 0.2
},
"walking": {
"animations": ["walk"],
"transitions": [
{ "idle": "query.modified_move_speed < 0.05" }
],
"blend_transition": 0.2
}
}
}
}
}Léelo así:
- El gólem empieza en
idley reproduce la animaciónidle. - En cuanto su velocidad supera 0.1, pasa a
walkingy reproducewalken su lugar. - Cuando baja de 0.05, vuelve a
idle. - Cada cambio se funde durante 0.2 segundos, así las piernas no saltan de golpe.
Los nombres dentro de animations son los apodos de la entidad de cliente, no los nombres largos que empiezan por animation.. Lo verás en el Paso 2.
Dos números distintos a propósito
La entrada (> 0.1) y la salida (< 0.05) usan números diferentes. Si fueran iguales, un gólem que se moviera justo a esa velocidad podría cambiar de habitación en cada fotograma y se vería tembloroso.
Campos del controlador
| Campo | Qué hace |
|---|---|
initial_state | El estado en el que empieza la criatura. Si lo omites, el juego busca un estado llamado default. |
states | Todos los estados, por nombre. |
Los nombres de los controladores empiezan por controller.animation.. Un buen patrón es controller.animation.<mob>.<job>, como controller.animation.ruby_golem.move.
Dentro de un estado
| Campo | Qué hace |
|---|---|
animations | Lo que se reproduce en este estado. Apodos, o apodos con una mezcla. |
transitions | Las puertas para salir de este estado, comprobadas en orden. |
blend_transition | Segundos que dura la transición de este estado al siguiente. |
blend_via_shortest_path | true hace que la transición gire los huesos por el camino más corto. |
on_entry | Cosas que se ejecutan una vez cuando la criatura entra en el estado. |
on_exit | Cosas que se ejecutan una vez cuando la criatura sale del estado. |
variables | Valores calculados para este estado, mira más abajo. |
particle_effects | Partículas que se muestran mientras dura este estado. |
sound_effects | Sonidos que suenan al entrar en este estado. |
Las partículas y los sonidos se explican en Eventos de animación.
Transiciones
transitions es una lista. Cada entrada tiene una clave (el estado al que ir) y una comprobación de Molang:
"transitions": [
{ "alert": "query.has_target" },
{ "swimming": "query.is_in_water" },
{ "idle": "query.modified_move_speed < 0.05" }
]- Las comprobaciones se hacen de arriba abajo. Gana la primera que sea verdadera.
- Solo ocurre una transición por fotograma.
- Si ninguna es verdadera, la criatura se queda donde está.
Así que pon primero la puerta más importante. Aquí, ver a un enemigo tiene prioridad sobre todo lo demás.
Mezclar dentro de un estado
Un estado puede reproducir varias animaciones a la vez. Cada una puede tener un valor de mezcla, igual que en scripts.animate:
"walking": {
"animations": [
"idle",
{ "walk": "query.modified_move_speed" }
]
}Un gólem lento muestra un poco de paso encima de su balanceo. Uno rápido muestra el paso completo.
Paso 2: conéctalo a la criatura
Un controlador se añade al mapa animations de la entidad de cliente, igual que una animación. Después lo reproduces desde scripts.animate:
"animations": {
"idle": "animation.ruby_golem.idle",
"walk": "animation.ruby_golem.walk",
"fists_up": "animation.ruby_golem.fists_up",
"look_at_target": "animation.common.look_at_target",
"move_controller": "controller.animation.ruby_golem.move"
},
"scripts": {
"animate": [
"look_at_target",
"move_controller"
]
}Fíjate en que idle y walk ya no están en animate. Ahora las reproduce el controlador. Si las dejas, se reproducen dos veces.
Puedes usar varios controladores a la vez. Cada uno guarda su propio estado actual. Una configuración habitual es un controlador para las piernas y el cuerpo, y otro para los brazos.
Paso 3: un estado de alerta
Vamos a hacer que el gólem levante los puños mientras tenga un objetivo. Añade un tercer estado y una puerta hacia él desde los otros dos:
"states": {
"idle": {
"animations": ["idle"],
"transitions": [
{ "alert": "query.has_target" },
{ "walking": "query.modified_move_speed > 0.1" }
],
"blend_transition": 0.2
},
"walking": {
"animations": ["walk"],
"transitions": [
{ "alert": "query.has_target" },
{ "idle": "query.modified_move_speed < 0.05" }
],
"blend_transition": 0.2
},
"alert": {
"animations": [
"fists_up",
{ "walk": "query.modified_move_speed" }
],
"transitions": [
{ "idle": "!query.has_target" }
],
"blend_transition": 0.3
}
}En alert el gólem mantiene los puños en alto y sigue caminando cuando te persigue.
Esperar a que termine una animación
Algunas animaciones deben reproducirse una vez y de principio a fin, como un rugido. Dos consultas te ayudan con eso:
| Consulta | Es verdadera cuando |
|---|---|
query.all_animations_finished | Todas las animaciones del estado han llegado al final |
query.any_animation_finished | Al menos una de ellas ha llegado al final |
"roar": {
"animations": ["roar"],
"transitions": [
{ "alert": "query.all_animations_finished" }
]
}Solo funcionan con animaciones que no se repiten en bucle. Una animación en bucle nunca termina.
on_entry y on_exit
on_entry se ejecuta una vez cuando la criatura entra en un estado, y on_exit una vez cuando sale. En un paquete de recursos ejecutan Molang, lo cual viene muy bien para asignar variables:
"alert": {
"on_entry": ["variable.times_alerted = (variable.times_alerted ?? 0) + 1;"],
"on_exit": ["variable.calm_since = query.life_time;"],
"animations": ["fists_up"],
"transitions": [{ "idle": "!query.has_target" }]
}En un paquete de comportamiento esas mismas listas también pueden ejecutar comandos y eventos de entidad. Mira Eventos de animación.
Variables de estado
Un estado puede calcular sus propios valores con variables. Lo más útil es remap_curve: convierte un rango de números en otro.
"walking": {
"variables": {
"swing": {
"input": "query.modified_move_speed",
"remap_curve": {
"0.0": 0.3,
"1.0": 1.0
}
}
},
"animations": [{ "walk": "variable.swing" }]
}Cuando la velocidad es 0, variable.swing vale 0.3. Cuando es 1, vale 1.0. Entre medias, el juego traza una línea recta. Así, incluso un gólem lento muestra un poco de paso.
Cuando algo falla
| Lo que ves | Causa más probable |
|---|---|
| No se reproduce nada | El controlador está en animations pero no en scripts.animate |
| Una animación se ve el doble de fuerte | Está a la vez en scripts.animate y en un estado del controlador |
| La criatura se queda atascada en un estado | Ninguna transición de salida llega a ser verdadera. Revisa el Molang de sus puertas |
| Una animación de una sola vez nunca termina | Tiene "loop": true, así que all_animations_finished nunca es verdadera |
| La criatura parpadea entre dos estados | Las comprobaciones de entrada y salida se solapan. Usa dos números distintos |
| El registro de contenido dice que falta un estado | Una transición apunta a un nombre de estado mal escrito |
Tienes más ayuda en Solución de problemas.
Y ahora qué
- Elige texturas y oculta partes del modelo con Controladores de renderizado.
- Lanza sonidos, partículas y comandos con Eventos de animación.
- Aprende más trucos de Molang en la guía de Molang.