Cambio de Animaciones de Personaje con Animator en Unity
Resumen
Logra que el salto y las transiciones de tu personaje se vean fluidas y profesionales. Aquí aprenderás a cambiar estados del Animator con variables booleanas, a configurar valores iniciales y a actualizar animaciones en tiempo real desde C#. Todo partiendo del flujo típico en Unity con Awake, Start y Update.
¿Cómo sincronizar el salto con el animator?
Para que el personaje no siga con la animación de correr al saltar, hay que modificar estados del animation controller usando las variables booleanas definidas en el Animator (por ejemplo, "isAlive" e "isOnTheGround"). La clave está en referenciar la componente Animator y actualizar sus parámetros según el estado del juego.
Accede a la componente del GameObject en Awake con GetComponent.
Usa SetBool para configurar parámetros booleanos del Animator.
Evita ligar las animaciones a entradas de usuario dentro de un if aislado; actualiza el estado en cada Update.
Ejemplo base en C#:
usingUnityEngine;publicclassPlayerController:MonoBehaviour{Animator animator;// Por defecto es privada si no se especifica.conststring STATE_ALIVE ="isAlive";conststring STATE_ON_THE_GROUND ="isOnTheGround";voidAwake(){ animator =GetComponent<Animator>();}voidStart(){// Configuración inicial de estados. animator.SetBool(STATE_ALIVE,true);// Empieza vivo. animator.SetBool(STATE_ON_THE_GROUND,false);// Según el punto de inicio.}voidUpdate(){// Actualiza el estado de suelo cada frame, fuera de condiciones de input. animator.SetBool(STATE_ON_THE_GROUND,IsTouchingTheGround());}boolIsTouchingTheGround(){// Implementación existente que devuelve true/false.returnfalse;// Placeholder: tu lógica real de colisión.}}
¿Qué constantes y convenciones mejoran la claridad?
Usar constantes de tipo string para los nombres de parámetros del Animator es una práctica simple y efectiva. Así evitas errores por escritura y centralizas cualquier cambio de nombre.
const indica un valor que no cambia en ejecución.
Convención de constantes: MAYÚSCULAS_CON_GUIONES_BAJOS para legibilidad.
Los valores deben coincidir exactamente con los nombres del Animator: "isAlive" y "isOnTheGround".
La palabra private es redundante si no especificas modificador: el campo sigue siendo privado.
Beneficios directos:
Menos errores por typos en SetBool.
Código más fácil de leer y mantener.
Cambio de nombres centralizado en una sola línea.
¿Cómo actualizar el estado en tiempo real y pausar el salto?
El método que determina si el personaje toca el suelo devuelve un booleano. Usa ese valor directamente para sincronizar el parámetro del Animator en cada Update. De este modo, el grafo de animaciones hace la transición correcta.
Actualiza isOnTheGround cada frame con el resultado de IsTouchingTheGround().
Si la animación de salto está en bucle y no encaja, hay dos alternativas comunes: reducir su velocidad o pausar la animación durante el salto.
Pausar/reanudar desde el método de contacto con el suelo:
boolIsTouchingTheGround(){bool touching =/* tu cálculo de colisión */;if(!touching){// Pausa la animación en el último frame de salto. animator.enabled =false;}else{// Reanuda la animación al tocar suelo. animator.enabled =true;}return touching;}
Recomendaciones prácticas:
Guarda el script antes de probar. Usa Command+S o Control+S.
Prueba con Play y verifica que el salto cambia de estado y vuelve a correr al tocar el suelo.
Ajusta velocidad o pausa según el efecto visual que busques.
Habilidades y conceptos puestos en práctica:
Control de estados con Animator y SetBool.
Uso de Awake, Start y Update para ciclo de vida.
Gestión de constantes string para parámetros del Animator.
Convenciones de nombres: camelCase vs MAYÚSCULAS_CON_GUIONES_BAJOS.
Lógica booleana para detección de suelo en IsTouchingTheGround().
Alternativas visuales: bajar velocidad o pausar con animator.enabled.
¿Tú qué prefieres para el salto: reducir velocidad o pausar la animación? Comparte tu enfoque y por qué te funciona mejor.
Una manera mas sencilla de que la animacion no tengamos que desactivarla como tal y podamos ver nuestra animacion completa, es yendo al componente de la animacion de salto y desactivamos la opcion de loop, y listo, cuando saltemos el salto solo se reproducira una sola vez sin tener que tocar codigo.
Messirve
Gracias!
La convención para escribir variables en mayúsculas separando las palabras con guión bajo se conoce como SCREAMING SNAKE CASE 😱 🐍:
Estándares de nomenclatura: Snake Case, Kebab Case & Camel Case
muchas gracias por tu aporte @juandc, es bueno tener en cuenta las convenciones y diferentes estándares para hacer cada día mejores códigos y mas entendibles.
gracias, información que cura!
ACLARACIÓN.
Acá no desactivamos la animación como tal, si no que desactivamos el componente Animator que tiene el GameObject que contiene el script.
Que en este caso es el script PlayerController y el GameObject es Player.
Exactamente ya que animator en este caso es una variable que tiene el Componente Animator del objeto Player , yo por eso para no confundirme le puse otro nombre a esta variable
El raycast roja no me sale en la pantalla Game, solo en Scene, por qué?
en tu editor haz click en la parte de Gizmos para que se vean también ahí
con eso estará visible en la pantalla de Game también como con el caso del profesor
mi personaje siempre se queda quieto y no pasa a otra animación, me podrían decir que hice mal?
A mí me ocurre exactamente lo mismo.
tienes configurado el componente animator en el objeto personaje? y todas las transiciones cómo hizo el profesor?
Porque a mi no me sale igual de fluido?, se tarda como medio segundo en cambiar de animación.
Puede ser debido a esto:
*Puede que el Has exit time esta activado y esto haga que la animación termine antes de la transición
*Puede ser por lag o problemas de rendimiento con Unity
*O puede ser que el codigo no se especifique bien o esta en un lugar no correspondiente
Espero que te haya servido :)
No me hace la transición de run a jump. Además el parámetro isOnTheGround se me queda marcado por defecto cuando le doy al play en Unity.
Alguien sabe que puede pasar? no encuentro el bug.
Buenas por alguna razon no logro que mi personaje se quede quiero al dar el salto. El codigo lo re contra compare con el del video y esta tal cual al que fui realizando hasta este mismo video... Sera que me olvide de tocar alguna opcion dentro de Unity? cual seria?. alguna idea?
Gracias
A mi me pasa exactamente igual, he revisado todo.
ayudenme a saber si entendi bien:
en esta linea, funciona segun yo asi, el animator toma el atributo de falso o verdadero(animator.setbool), despues se le pasa como parametro que es lo que va a cambiar de estado(STATE_ON_THE_GROUND) el cual vale true y que asu vez esta agarradod e una animacion.
Entonces declarado en el update dice asi, oye animator, coloca verdadero o falso a la animacion que vale true llamada STATE_on_the_ground, pero dependiendo del resultado del metodo is on the ground
yo entendí muy bien todo , pero esa linea animator.SetBool(STATE_ON_THE_GROUND, IsTouchingTheGound());
no la comprendo bien ...
Sí de hecho es lo que yo entendí , aqui pongo lo que segun yo entendí
En este caso animator es la variable que contiene al componente Animator del objeto Player y pone con SetBool(STATE_ON_THE_GROUND, IsTouchingTheGround())
primero STATE_ON_THE_GROUND es el parámetro de isGrounded de la animacion que agregamos al PlayerController
Segundo isTouchingTheGround() es el método que usamos para verificar si esta en el suelo o no y regresa ya sea un true o un false
buenas que pasa, tengo un poblemita y es que me salen estos errores y aparte no realizan las animaciones cuando se deben de ejecutar, Muchas graciassss espero me puedan ayudar
que creen, ya lo resolvi solo tuve que hacer de nuevo los parametros y todo eso, muchas gracias :)
Jaj yo también estoy usando mis propios Assets :)
Encontré una forma de pausar la animación de SALTAR en el último frame, primero deben bucar la animación llamada "Jump", no deben elegir el controlador de la animación de saltar, sino la misma animación, luego darle click, en la parte de la derecha dice "Loop Time", que está activada, la desactivan y ahora cuando salten, la animación no estará en bucle
Costó pero salio. Si no les llega a salir, como a mi, lo que les recomiendo que hagan es eliminar las flechas de la animación y ponerlas de nuevo. De esa manera elimine el "bug" del cambio de animación al saltar.
Antonio eres Dios
Tu sabes cuanto tiempo llevo analizando el script y el animator ese para que me salga no solo la animacion, sino la rayita esa. UN MES bro, UN MES ENTERO.
de verdad muchisimas gracias
Por que cuando salta mi personaje, no se anima el "JUMP", solo hace "RUN" mientras salta. Incluso use el docdigo del profe, y no me sale ninguna diferencia.
tienes configurada la transición de run a jump?
Genial
El personaje sigue corriendo cuando brinco y ya segui los pasos del profesor aun no encuentro como solucionarlo si alguien me peude ayudar
Mi personaje al saltar sigue corriendo, llevo rato buscando como se hace, segui los pasos del profesor
no me funciona me pone como que no existe le estoy poniendo otra traslacion de quedarse quieto a caminar pero siempre me falla
Alguien me puede ayudar, lo que pasa es que IsTouchinTheGriund siempre me da true y por tanto el personaje puede saltar indefinidamente. Creo que el problema esta en el Raycast, ya que por alguna razón siempre detecta el suelo.
<using System.Collections;using System.Collections.Generic;using UnityEngine;publicclassPlayerController:MonoBehaviour{//Variables del movimiento del personajepublic float jumpForce = 6f;Rigidbody2D rigidBody;//Creamos var tipo Rigidbody2DAnimator animator;const string IS_DEAD="IsDead";const string STATE_ON_THE_GROUND="IsOnGround";publicLayerMask groundMask;// Start is called before the first frame updateprivatevoidAwake(){ rigidBody =GetComponent<Rigidbody2D>();//La variable RigidBody sabe a cual rigidBody referirse :v animator =GetComponent<Animator>();// groundMask = GetComponent<PlayerController.GroundMask>;}voidStart(){ animator.SetBool(IS_DEAD,false); animator.SetBool(STATE_ON_THE_GROUND,false);}// Update is called once per framevoidUpdate(){// if(n==100){// animator.SetBool(STATE_ON_THE_GROUND, true);// }if(Input.GetKeyDown(KeyCode.Space)||Input.GetMouseButtonDown(0))//0=izquierdo 1=derecho 2=ruedita{Jump();} animator.SetBool(STATE_ON_THE_GROUND,IsTouchingTheGround());Debug.DrawRay(this.transform.position,Vector2.down*1.0f,Color.red);}voidJump(){if(IsTouchingTheGround()){ rigidBody.AddForce(Vector2.up*jumpForce,ForceMode2D.Impulse);//Modo Force = constante. Modo Impulse = impulso...}} bool IsTouchingTheGround(){if(Physics2D.Raycast(this.transform.position,Vector2.down*1.0f,groundMask))//0.2f=20cm{//TODO: programar logica de contacto con el sueloreturntrue;}else{returnfalse;}}}//Arifureta Shokugio Sekai>
Revisa la función misma, probablemente allí encuentres el error.
Recomendación: revisa la longitud del rayo en Physics2D.raycast() o los valores que tu función retorna
Buenas, este es mi codigo, no me hace la transicion a JUMP cuando salto. ya revise todo e incluso descargue el codigo del profe pero sigue sin funcionar. el animator no me anda
//Variables del movimiento del personajepublic float jumpForce = 6f;privateRigidbody2D rigidBody;Animator animator;const string STATE_ALIVE="isAlive";const string STATE_ON_THE_GROUND="isOnTheGround";publicLayerMask groundMask;voidAwake(){ rigidBody =GetComponent<Rigidbody2D>(); animator =GetComponent<Animator>();}voidStart(){ animator.SetBool(STATE_ALIVE,true); animator.SetBool(STATE_ON_THE_GROUND,true);}voidUpdate(){//Asignamos la tecla espacio y clickear el mouse para saltarif(Input.GetKeyDown(KeyCode.Space)||(Input.GetMouseButtonDown(0))){Jump();} animator.SetBool(STATE_ON_THE_GROUND,IsTouchingTheGround());Debug.DrawRay(this.transform.position,Vector2.down*1.5f,Color.red);}voidJump(){if(IsTouchingTheGround()){ rigidBody.AddForce(Vector2.up* jumpForce,ForceMode2D.Impulse);}}//Nos indica si el personaje esta o no tocando el suelo bool IsTouchingTheGround(){// Desde donde estoy trazo una raya hacia abajo de 20cm contra la mascara del sueloif(Physics2D.Raycast(this.transform.position,Vector2.down,1.4f, groundMask)){returntrue;}else{returnfalse;}}}