Jumping animation in a 2D platformer

I am making a 2D platformer game and my character moves around and jump just fine. I have the animation for the idle and walking, but when I jump, the walking animation continues.

I was wondering if anyone knew why. Am i missing something in my code, or the Animator Controller ?

public class CharacterMovement : MonoBehaviour
{
    public float moveSpeed = 5.0f;
    public float runSpeedMultiplier = 2.0f;
    public float jumpForce = 10.0f;
    public float attackCooldown = 1.0f;

    private bool isRunning = false;
    private bool isAttacking = false;
    private bool canAttack = true;

    private Rigidbody2D rb;
    private Animator animator; 

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
        rb.freezeRotation = true; 

    }

    void Update()
    {
        // Movement
        float horizontalInput = Input.GetAxis("Horizontal");
        Vector2 movement = new Vector2(horizontalInput, 0);

        animator.SetFloat("Speed", Mathf.Abs(horizontalInput));

        if (isRunning)
        {
            movement *= moveSpeed * runSpeedMultiplier;
        }
        else
        {
            movement *= moveSpeed;
        }

        rb.velocity = new Vector2(movement.x, rb.velocity.y);

        // Flip the character's sprite based on the movement direction
        if (horizontalInput < 0)
        {
            transform.localScale = new Vector3(Mathf.Abs(transform.localScale.x) * -1, transform.localScale.y, transform.localScale.z);
        }
        else if (horizontalInput > 0)
        {
            transform.localScale = new Vector3(Mathf.Abs(transform.localScale.x), transform.localScale.y, transform.localScale.z);
        }

        
        // Jumping
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (IsGrounded())
            {
                rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
                animator.SetBool("IsJumping", true);
            }

            bool grounded = IsGrounded();

            animator.SetBool("IsJumping", !grounded);
        }

        // Running
        if (Input.GetKey(KeyCode.LeftControl))
        {
            isRunning = true;
        }
        else
        {
            isRunning = false;
        }

        // Attacking
        if (Input.GetKeyDown(KeyCode.LeftShift) && canAttack)
        {
            StartCoroutine(AttackCooldown());
            StartAttackAnimation();
        }
                
    }

    public void OnLanding ()
    {
        animator.SetBool("IsJumping", false);
    }

    // Detect if the character is grounded
    bool IsGrounded()
    {
        RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 0.1f);
        return hit.collider != null;
    }

    // Cooldown for attacks
    IEnumerator AttackCooldown()
    {
        canAttack = false;
        yield return new WaitForSeconds(attackCooldown);
        canAttack = true;
    }

    // Trigger the attack animation
    void StartAttackAnimation()
    {
  
        animator.SetTrigger("Attack"); // "Attack" is the name of the attack animation trigger
    }
}

It’s the code!

Your jump does this, if we simplify it down a bit:

if (grounded) {
    animator.SetBool("IsJumping", true);
}

animator.SetBool("isJumping", !isGrounded);

Which means that you always set the bool false again immediately!

There’s a few ways to solve this. You could wait a little bit after you jump before you allow setting isGrounded to true again, you could have the definition of IsGrounded be “time since jumped is more than x and there’s no ground under my feet”, or you could solve it in the AnimatorController by passing an IsGrounded bool to it as well, and then not transition out of the jump state before a certain amount of time has passed.

1 Like