Configura un Animator fluido en Unity: dos blend trees (idle y movement), transiciones limpias con walking y parámetros last horizontal y last vertical que mantienen al personaje mirando su última dirección. Aquí verás cómo depurar el grafo y sincronizarlo desde tu controlador sin sobrecargar Update.
¿Qué cambia en el animator con blend trees y walking?
Para un resultado consistente, se utiliza un blend tree de player idle (sin barra baja) con cuatro poses: facing right, left, up y down, gobernadas por last horizontal y last vertical. El estado idle original ya no es necesario.
Elimina el idle original: usa player idle (blend tree) como estado por defecto.
Crea dos transiciones: de idle a movement con walking = true y de movement a idle con walking = false.
Desactiva Exit Time y la duración fija de las animaciones. Mejora la fluidez.
Conserva los parámetros last horizontal y last vertical en el blend tree de idle.
Así, el grafo alterna entre player idle y player movement solo con el booleano walking, manteniendo la pose según el último vector registrado.
¿Cómo configurar el player controller para sincronizar animator?
Desde el controlador, se derivan y envían los parámetros al Animator para que refleje el movimiento y la última dirección. Además, se evita crear strings en Update por rendimiento: se definen constantes arriba y se reutilizan.
¿Qué variables y constantes declarar?
Estado de caminata y último movimiento.
Constantes para nombres de parámetros del Animator.
// Variables de estadoprivatebool walking =false;// por defecto paradopublicVector2 lastMovement = Vector2.zero;// sin dirección previa// Constantes de parámetros del Animatorprivateconststring lastHorizontal ="LastHorizontal";privateconststring lastVertical ="LastVertical";privateconststring walkingState ="Walking";// evita colisión con bool walking
Claves:
No uses strings literales en Update. Cárgalos una sola vez como constantes.
lastMovement guarda la última dirección válida para el idle.
¿Cómo actualizar walking y lastMovement en update?
Inicia cada frame con walking = false.
En los if de movimiento horizontal y vertical: marca walking = true y sobrescribe lastMovement con el eje activo.
Notifica al Animator con SetBool y SetFloat.
voidUpdate(){// Por defecto, no caminamos en este frame walking =false;// if (condición de movimiento horizontal) { ... }// walking = true;// lastMovement = new Vector2(Input.GetAxisRaw("Horizontal"), 0f);// if (condición de movimiento vertical) { ... }// walking = true;// lastMovement = new Vector2(0f, Input.GetAxisRaw("Vertical"));// Sincronización con Animator animator.SetBool(walkingState, walking); animator.SetFloat(lastHorizontal, lastMovement.x); animator.SetFloat(lastVertical, lastMovement.y);}
Puntos clave:
walking solo es verdadero si hubo entrada válida en el frame.
SetFloat de last horizontal y last vertical mantiene el facing correcto en idle.
Resultado: transiciones suaves entre blend trees y una pose idle coherente.
¿Cómo depurar sprites y comprobar que el idle mira la última dirección?
Si el personaje siempre mira hacia abajo tras parar, revisa que cada pose del blend tree de idle esté bien asignada. Al corregir los sprites, el personaje queda mirando la última dirección registrada por lastMovement.
facing up: usa el sprite “player 15”.
facing down: usa el sprite “player 0”.
facing left: usa el sprite “player 5”.
facing right: usa el sprite “player 10”.
Después de actualizar las referencias, prueba en Play: al moverte arriba/izquierda/abajo/derecha, el idle debe conservar esa orientación gracias a walking, last horizontal y last vertical. Si tienes dudas o quieres compartir tu configuración, comenta qué parte del grafo o del código te gustaría revisar.
Para evitar que el conejo por un instante parezca que mira hacia otra direccion antes de quedarse quieto podemos poner el parámetro "Transition Duratior" de las transiciones del animator en 0.
Cuando muevo el Jugador hacia la izquierda, arriba o abajo, al final mira a la derecha antes de voltear, Tengo al Conejo Jackson? 🧟♂️🧟♂️🧟♂️
Solución: Vas a la transición de movimiento a quieto en el recuadro donde sale la linea de tiempo de de la animación, en la parte de arriba, donde se indica el tiempo, se vera una franja azul la cual deberemos acortar y llevarla hasta el inicio de la animación, con eso ya no hará ese movimiento raro hacia la derecha cuando se detiene el conejo
Como menciona Victor, o bien simplemente cambiando la transition duration a 0 en ambas direcciones
Aquí con los cambios agregados en esta clase:
using System.Collections;using System.Collections.Generic;using UnityEngine;publicclassPlayerController:MonoBehaviour{public float speed =4.0f;private bool walking =false;publicVector2 lastMovement =Vector2.zero;privateconst string horizontal ="Horizontal";privateconst string vertical ="Vertical";privateconst string lastHorizontal ="LastHorizontal";privateconst string lastVertical ="LastVertical";privateconst string walkingState ="Walking";privateAnimator animator;// Start is called before the first frame updatevoidStart(){ animator =GetComponent<Animator>();}// Update is called once per framevoidUpdate(){// s = v*t; walking =false;//Movimiento horizontalif(Mathf.Abs(Input.GetAxisRaw(horizontal))>0.5f){this.transform.Translate(newVector3(Input.GetAxisRaw(horizontal)*speed*Time.deltaTime,0,0)); walking =true; lastMovement =newVector2(Input.GetAxisRaw(horizontal),0);}//Movimiento verticalif(Mathf.Abs(Input.GetAxisRaw(vertical))>0.5f){this.transform.Translate(newVector3(0,Input.GetAxisRaw(vertical)*speed*Time.deltaTime,0)); walking =true; lastMovement =newVector2(0,Input.GetAxisRaw(vertical));} animator.SetFloat(horizontal,Input.GetAxisRaw(horizontal)); animator.SetFloat(vertical,Input.GetAxisRaw(vertical)); animator.SetBool(walkingState, walking); animator.SetFloat(lastHorizontal, lastMovement.x); animator.SetFloat(lastVertical, lastMovement.y);}}
Muy importante el repasar todos estos puntos antes de seguir con las clases, puesto que son muchos parámetros en tomar en cuenta, les invito a repasar un poco y entender realmente cómo funciona.😄
El conejo siempre se queda viendo hacia la derecha en el Idle, cómo lo arreglo?
Mis variables LastHorizontal y LastVertical siempre se regresan a 0 al dejarlas de presionar ¿cómo lo puedo solucionar?
Para evitar ese flick del personaje ponga el "Transition Duratior" en 0 de las flechas.
IMPORTANTE !
las constantes tipo string deben asignarse de igual forma como lo asignaron en los parametros del animator del player, no me funcionaba por una espacio, revisar muy bien.
Genial
tengo un extraño comportamiento, he seguido todo al pie de la letra, pero cuando se mueve de izquierda a derecha solo se puede ver el frame sin animacion
Tal vez podrías checar si la animación está correcta, me refiero a que los sprites si cambian.
si, de hecho pense que habia hecho mal alguna animacion, lo hice con el otro metodo de animacion y sin problema, volvi a hacer la animacion y nada no se que pasa
Mi personaje siempre queda Player_Facing_Up, a alguien le paso algo similar? Saben donde puede estar el problema?