Hey everyone !
I’m new to Unity, and I’m trying to create my first little game. I did a map, and a character that can move, and even some animations !
I have one problem, though… When I press wasd, my character goes in one direction, and uses the proper animation, but when I stop pressing the keys, my character isn’t facing the direction he was heading to…
I used 2 blend trees, one with all my idle animations, and one with my walking animations, but when it is supposed to be idling in any direction, it just get stuck and idling with the “Idle_Down” animation… Is there so code that I need to add ?
Here’s my Controller script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed = 5f;
public Rigidbody2D rb;
public Animator animator;
Vector2 movement;
// Update is called once per frame
void Update()
{
// Input
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
animator.SetFloat("Horizontal", movement.x);
animator.SetFloat("Vertical", movement.y);
animator.SetFloat("Speed", movement.sqrMagnitude);
}
void FixedUpdate()
{
// Movement
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
}
I understand that it can be confusing, I even myself don’t really know how to precisely explain my problem ^^"
WECOME! Bravo for a good post, with formatted code and a clear description and everything.
I am going to speculate that the problem is when you come to rest you are supplying 0 and 0 for x and y to your animator parameters.
When you are going 0 and 0, you’re not really facing anywhere, so what you probably want is to leave it facing what it was before you stopped moving, most of the time anyway.
Try this:
Put lines 21 and 22 above into an if statement that checks the size of movement and only sets those animator parameters if you are moving at a certain minimum amount, something like this:
if (movement.magnitude > 0.01f)
{
animator.SetFloat("Horizontal", movement.x);
animator.SetFloat("Vertical", movement.y);
}
You still want to leave the speed setter though, so you fully come to a zero animation speed, if that makes a difference in your animation state machine.
If i understand your problem correct you must save your last movement direction in your controller and pass this direction to your idle blend tree.
Therefore you must give the idle blend tree other variable names “HorizontalIdle” “VerticalIdle” and only call it if your character is not running. The other variables could be defined like this:
Vector2 movementLast;
// Update is called once per frame
void Update()
{
// Input
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
animator.SetFloat("Horizontal", movement.x);
animator.SetFloat("Vertical", movement.y);
animator.SetFloat("Speed", movement.sqrMagnitude);
if (movement.x == 0 && movement.y == 0) {
animator.SetFloat("HorizontalIdle", movementLast.x);
animator.SetFloat("VerticalIdle", movementLast.y);
} else {
animator.SetFloat("HorizontalIdle", 0f);
animator.SetFloat("VerticalIdle", 0f);
}
if (movement.x != 0) movementLast.x = movement.x;
if (movement.y != 0) movementLast.y = movement.y;
}
Its not perfect at all you should use the velocity of the players rigidbody to drive your animations.