Cancel Movement on Action (like attacking)

Hey All,

Once again I’m stumped. I think it’s because I used the video to make my movement system. I might switch to “Horizontal” and “Vertical” but right now I don’t have the energy:

Which, the movement works great, but I want to implement cancelling the movement input when an attack animation is being played. I’ve tried everything, but can’t seem to come up with a solution. Code below. Please be nice, I know it’s messy and I’m super new to this. All suggestions welcome.

public class ControllerCharacter : MonoBehaviour
{
    public float speed = 20f;
    private Rigidbody2D myRB;
    private Vector3 moveDir;
   
    private Vector3 dashDir;
    public float dashSpeed;
    public float dashCooldownTime = 0.5f;
    private enum State
    {
        Normal,
        Dashing,
    }

    private Animator myAnim;

    private bool isDodgeButtonDown;
    public ParticleSystem dust;

    public float dodgeCooldownTime = 0.5f;
    private float nextDodgeTime = 0;
    private float nextDashTime = 0;

    private State state;


    private void Awake()
    {
        myRB = GetComponent<Rigidbody2D>();
        myAnim = GetComponent<Animator>();
        state = State.Normal;
    }

  
    private void Update()
    {
        switch (state)
        {
            case State.Normal:

                float moveX = 0f;
                float moveY = 0f;

                if (Input.GetKey(KeyCode.W))
                {
                    moveY = +1f;
                }
                if (Input.GetKey(KeyCode.S))
                {
                    moveY = -1f;
                }
                if (Input.GetKey(KeyCode.A))
                {
                    moveX = -1f;
                }
                if (Input.GetKey(KeyCode.D))
                {
                    moveX = +1f;
                }

                moveDir = new Vector3(moveX, moveY).normalized;
                myAnim.SetFloat("MoveX", moveX);
                myAnim.SetFloat("MoveY", moveY);


                if (moveX == 1 || moveX == -1 || moveY == 1 || moveY == -1)
                {
                    myAnim.SetFloat("LastMoveX", moveX);
                    myAnim.SetFloat("LastMoveY", moveY);
                }


                if (Time.time > nextDodgeTime)
                {
                    if (Input.GetKeyDown(KeyCode.C))
                    {
                        //isDodgeButtonDown = true;
                        myAnim.SetBool("IsAttacking", true);
                       
                        nextDodgeTime = Time.time + dodgeCooldownTime;
                    }
                }


                if (Time.time > nextDashTime)
                {
                    if (Input.GetKeyDown(KeyCode.Space))
                    {
                        myAnim.SetBool("IsDashing", true);
                        dashDir = moveDir;
                        dashSpeed = 80f;
                        state = State.Dashing;
                        CreateDust();
                        nextDashTime = Time.time + dashCooldownTime;
                    }
                }


                if (Time.time > nextDashTime)
                {
                    if (Input.GetKeyDown(KeyCode.V))
                    {
                        myAnim.SetBool("IsSlashing1", true);
                        //dashDir = moveDir;
                        //dashSpeed = 2f;
                        //state = State.Dashing;
                       
                        nextDashTime = Time.time + dashCooldownTime;
                    }
                }


                if (Time.time > nextDashTime)
                {
                    if (Input.GetKeyDown(KeyCode.B))
                    {
                        myAnim.SetBool("IsSlashing2", true);
                        //dashDir = moveDir;
                        //dashSpeed = 2f;
                        //state = State.Dashing;
                       
                        nextDashTime = Time.time + dashCooldownTime;
                    }
                }

                break;
            case State.Dashing:

                float dashSpeedDropMultiplier = 5f;
                dashSpeed -= dashSpeed * dashSpeedDropMultiplier * Time.deltaTime;

                float dashSpeedMinimum = 50f;
                if (dashSpeed < dashSpeedMinimum)
                {
                    state = State.Normal;
                }
                break;
        }
    }


    private void FixedUpdate()
    {
        switch (state)
            {
                    case State.Normal:
                myRB.velocity = moveDir * speed;

                if (isDodgeButtonDown)
                {
                    float dodgeAmount = 2f;

                    Vector3 dodgePosition = transform.position + moveDir * dodgeAmount;

                    myRB.MovePosition(transform.position + moveDir * dodgeAmount);

                    isDodgeButtonDown = false;
                }
                        break;
                    case State.Dashing:
                        myRB.velocity = dashDir * dashSpeed;
                        break;
            }
    }

}

Wrap your Input.GetKey(WASD) code with an IF (NotInAttack) then yourcode Else moveX,MoveY=0

If you want to trigger this from your animation directly, use an animation event to set the variable

Thanks alot for the help. I’m sorry, but I am SO new to this. When I wrap the movement code in IF(NotInAttack) do I have to declare this up top as Public bool NotInAttack;, or something to that effect?

Just set a new state enum, attacking. You switch to attacking state, in which you won’t have the move code which you wrote inside the normal state.

Solve one, another pops up. I passed the Attacking State, and the character stops moving when you press the attack button, but, it won’t let me move afterward but the moving animation keeps playing. Here’s my updated code.

private Rigidbody2D myRB;
    private Animator myAnim;
    public ParticleSystem dust;
    private Vector2 movement;
    private Vector2 moveDir;
    public float speed = 20f;
    private Vector2 dashDir;
    private float dashSpeed;
    private float nextDashTime = 0;
    public float dashCooldownTime = 0.5f;
    private State state;

    private enum State
    {
        Normal,
        Dashing,
        Attacking,
    }

    void Start()
    {
        myRB = GetComponent<Rigidbody2D>();
        myAnim = GetComponent<Animator>();
        state = State.Normal;
    }

    void Update()
    {
        switch (state)
        {
            case State.Normal:


                //Moving
                movement.x = Input.GetAxisRaw("Horizontal");
                movement.y = Input.GetAxisRaw("Vertical");
                myAnim.SetFloat("MoveX", movement.x);
                myAnim.SetFloat("MoveY", movement.y);

                moveDir = new Vector2(movement.x, movement.y).normalized;

                if (Input.GetAxisRaw("Horizontal") == 1 || Input.GetAxisRaw("Horizontal") == -1 || Input.GetAxisRaw("Vertical") == 1 || Input.GetAxisRaw("Vertical") == -1)
                {
                    myAnim.SetFloat("LastMoveX", Input.GetAxisRaw("Horizontal"));
                    myAnim.SetFloat("LastMoveY", Input.GetAxisRaw("Vertical"));
                }

                //Attacking
                if (Input.GetKeyDown(KeyCode.C))
                {
                    myAnim.SetBool("IsAttacking", true);
                    state = State.Attacking;
                }

                if (Input.GetKeyDown(KeyCode.V))
                {
                    myAnim.SetBool("IsSlashing1", true);
                    state = State.Attacking;
                }

                if (Input.GetKeyDown(KeyCode.B))
                {
                    myAnim.SetBool("IsSlashing2", true);
                    state = State.Attacking;
                }

                //Dashing
                if (Input.GetAxisRaw("Horizontal") == 1 || Input.GetAxisRaw("Horizontal") == -1 || Input.GetAxisRaw("Vertical") == 1 || Input.GetAxisRaw("Vertical") == -1)
                {
                    if (Time.time > nextDashTime)
                    {
                        if (Input.GetKeyDown(KeyCode.Space))
                        {
                            dashDir = movement;
                            dashSpeed = 80f;
                            state = State.Dashing;
                            myAnim.SetBool("IsDashing", true);
                            CreateDust();
                            nextDashTime = Time.time + dashCooldownTime;
                        }
                    }
                }


                break;
                //Dashing State
            case State.Dashing:
                float dashSpeedDropMultiplier = 5f;
                dashSpeed -= dashSpeed * dashSpeedDropMultiplier * Time.deltaTime;

                float dashSpeedMinimum = 50f;
                if (dashSpeed < dashSpeedMinimum)
                {
                    state = State.Normal;
                }
                break;
            case State.Attacking:
                break;
           

        }
    }

    void FixedUpdate()
    {
        switch (state)
        {
            case State.Normal:

                //Moving
                myRB.MovePosition(myRB.position + moveDir * speed * Time.fixedDeltaTime);

            
                break;
                //Dashing State
            case State.Dashing:
                myRB.velocity = dashDir * dashSpeed;
                break;
            case State.Attacking:
              
                break;
           
        }
    }

    //Particle System
    void CreateDust()
    {
        dust.Play();
    }

In my enemy script, I use animation events to set the state back to normal after they finish attacking.
Create a public function SetStateNormal() and call this function when youre done with the attack animation.

So should I not even bother with the State Machine?

Well, inside the set state normal, you set the state machine normal.

I’m an idiot. Thank you for the help.