Toggling Animations (New Input System)

Hey all -

I’m trying to have my character walk, attack, and jump. I’ve got walking and jumping down pretty well (I think) but whenever I press the OnAttack button, it changes isAttacking to true but doesn’t change it back to false when I release it. Any help on this?

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerMovement : MonoBehaviour
{
    [SerializeField] float walkSpeed = 1f;
    [SerializeField] float jumpForce = 1f;
    [SerializeField] float attackSpeed = 1f;

    Vector2 moveInput;
    Rigidbody2D playerRigidBody;
    Animator playerAnimator;
    CapsuleCollider2D playerCapsuleCollider;

    public bool isGrounded;
    public bool canDoubleJump;
    public bool isAttacking;

    void Start()
    {
        playerRigidBody = GetComponent<Rigidbody2D>();
        playerAnimator = GetComponent<Animator>();
        playerCapsuleCollider = GetComponent<CapsuleCollider2D>();
    }

    void Update()
    {
        isGrounded = playerCapsuleCollider.IsTouchingLayers(LayerMask.GetMask("Ground"));

        Walk();

        playerAnimator.SetBool("IsWalking", Mathf.Abs(playerRigidBody.velocity.x) > 0 && !isAttacking && isGrounded);
        playerAnimator.SetBool("IsJumping", !isGrounded);
        playerAnimator.SetBool("IsAttacking", Mathf.Abs(playerRigidBody.velocity.x) > 0 && isAttacking && isGrounded);

        FlipSprite();
    }

    void OnMove(InputValue value)
    {
        moveInput = value.Get<Vector2>();
    }

    private void OnAttack(InputValue value)
    {
        if (value.isPressed)
        {
            isAttacking = true;
        }
        else
        {
            isAttacking = false;
        }
    }

    void OnJump(InputValue value)
    {
        if (isGrounded)
        {
            canDoubleJump = true;
        }

        if (value.isPressed)
        {
            if (isGrounded)
            {
                playerRigidBody.velocity = new Vector2(playerRigidBody.velocity.x, jumpForce);
            }
            else
            {
                if (canDoubleJump)
                {
                    playerRigidBody.velocity = new Vector2(playerRigidBody.velocity.x, jumpForce);
                    canDoubleJump = false;
                }
            }
        }
    }

    void Walk()
    {
        float speedMultiplier = isAttacking ? attackSpeed : walkSpeed;
        Vector2 playerVelocity = new Vector2(moveInput.x * speedMultiplier, playerRigidBody.velocity.y);
        playerRigidBody.velocity = playerVelocity;
    }

    void FlipSprite()
    {
        bool playerHasHorizontalSpeed = Mathf.Abs(playerRigidBody.velocity.x) > Mathf.Epsilon;

        if (playerHasHorizontalSpeed)
        {
            transform.localScale = new Vector2(Mathf.Sign(playerRigidBody.velocity.x), 1f);
        }
    }
}

If it helps, this is the functionality I’m going for but just in the new input system. (I’d like to use my OnAttack button versus assigning just one key to it.

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField] float walkSpeed = 1f;
    [SerializeField] float jumpForce = 1f;
    [SerializeField] float attackSpeed = 1f;

    Rigidbody2D playerRigidBody;
    Animator playerAnimator;
    CapsuleCollider2D playerCapsuleCollider;

    private bool isGrounded;
    private bool canDoubleJump;

    void Start()
    {
        playerRigidBody = GetComponent<Rigidbody2D>();
        playerAnimator = GetComponent<Animator>();
        playerCapsuleCollider = GetComponent<CapsuleCollider2D>();
    }

    void Update()
    {
        if (!Input.GetButton("Fire3"))
        {
            playerRigidBody.velocity = new Vector2(walkSpeed * Input.GetAxis("Horizontal"), playerRigidBody.velocity.y);
        }
        else
        {
            playerRigidBody.velocity = new Vector2(attackSpeed * Input.GetAxis("Horizontal"), playerRigidBody.velocity.y);
        }

        isGrounded = playerCapsuleCollider.IsTouchingLayers(LayerMask.GetMask("Ground"));

        if (isGrounded)
        {
            canDoubleJump = true;
        }

        if (Input.GetButtonDown("Jump"))
        {
            if (isGrounded)
            {
                playerRigidBody.velocity = new Vector2(playerRigidBody.velocity.x, jumpForce);
            }
            else
            {
                if (canDoubleJump)
                {
                    playerRigidBody.velocity = new Vector2(playerRigidBody.velocity.x, jumpForce);
                    canDoubleJump = false;
                }
            }
        }

        playerAnimator.SetBool("IsJumping", !isGrounded);
        playerAnimator.SetBool("IsWalking", Mathf.Abs(playerRigidBody.velocity.x) > 0 && !Input.GetButton("Fire3") && isGrounded);
        playerAnimator.SetBool("IsAttacking", Input.GetButton("Fire3") && isGrounded && Mathf.Abs(playerRigidBody.velocity.x) > 0);
        FlipSprite();
    }

    void FlipSprite()
    {
        bool playerHasHorizontalSpeed = Mathf.Abs(playerRigidBody.velocity.x) > Mathf.Epsilon;

        if (playerHasHorizontalSpeed)
        {
            transform.localScale = new Vector2(Mathf.Sign(playerRigidBody.velocity.x), 1f);
        }
    }
}

Hey Samual, I am fairly new to animations, but one thing I encountered with the new input system is input actions, which I don’t see here. I don’t recall how they worked exactly, but I remember how I used them, along the lines of:

action.started += context =>... action.performed += context =>... action.interrupted += context => ...
I sadly forgot what this was about, as I stopped the project in which I used it. I would recommend you make some research.(e.g. Actions | Input System | 1.5.1) Regarding the issue, maybe OnAttack is only called on key down and not every time you act?
This was the video I used to educate myself on the new input system https://www.youtube.com/watch?v=tXDgSGOEatk&t=1248s.