Animation Playing Twice

I’m a total newbie to Unity, so I’ve been toying around with a lot of features. I have tried a lot of things here already, so I’m turning to this community. I am trying to just get this to play the attack animation normally, but no matter what I do, it always seems to play it twice when I click only once. Everything else seems to be working, I just can’t for the life of me figure out what is wrong here. Thanks in advance for the help.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    private Rigidbody2D rb;
    private BoxCollider2D coll;
    private SpriteRenderer sprite;
    private Animator anim;

    private bool isAttacking = false;
    private bool canChangeDirection = true;
    private bool canAttack = true;
    private float nextFire;
    [SerializeField] private float attackCooldown = 1f;

    private GameObject attackObject;
    private SpriteRenderer attackSpriteRenderer;

    [SerializeField] private LayerMask jumpableGround;

    private float dirX = 0f;
    [SerializeField] private float moveSpeed = 7f;
    [SerializeField] private float jumpForce = 14f;

    private enum MovementState { idle, running, jumping, falling, attacking }

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        coll = GetComponent<BoxCollider2D>();
        sprite = GetComponent<SpriteRenderer>();
        anim = GetComponent<Animator>();

        attackObject = transform.Find("SlashObject").gameObject;
        attackSpriteRenderer = attackObject.GetComponent<SpriteRenderer>();
    }

    // Update is called once per frame
    private void Update()
    {
        if (isAttacking)
        {
            canAttack = false;
        }
        if (Time.time >= nextFire)
        {
            canAttack = true;
        }
        else
        {
            canAttack = false;
        }
        dirX = Input.GetAxis("Horizontal");
        rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);

       
        if (Input.GetButtonDown("Jump") && IsGrounded())
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
        }
        if (Input.GetButtonDown("Fire1") && canAttack)
        {
            isAttacking = true;
            nextFire = Time.time + attackCooldown;
        }

        UpdateAnimationState();
    }

    //Automatically called at the last frame of the attack animation
    public void EndAttackAnimation()
    {
        isAttacking = false;
    }

    //Automatically called at the first frame of the attack animation to initiate the slashObject animation (seperate object of the player which does the attack animation)
    public void StartAttackAnimation()
    {
        attackObject.GetComponent<Animator>().SetTrigger("slash");
    }

    private void UpdateAnimationState()
    {
        MovementState state = MovementState.idle;
        if (isAttacking && state != MovementState.attacking)
        {
            state = MovementState.attacking;
            canChangeDirection = false;
        }
        else if (rb.velocity.y > .1f)
        {
            state = MovementState.jumping;
            canChangeDirection = true;
        }
        else if (rb.velocity.y < -.1f)
        {
            state = MovementState.falling;
        }
        else if (dirX > 0f && canChangeDirection && !isAttacking)
        {
            state = MovementState.running;
            sprite.flipX = false;
            attackSpriteRenderer.flipX = false;
            attackObject.transform.localPosition = new Vector3(0.92f, 0.31f, 0f);
        }
        else if (dirX < 0f && canChangeDirection && !isAttacking)
        {
            state = MovementState.running;
            sprite.flipX = true;
            attackSpriteRenderer.flipX = true;
            attackObject.transform.localPosition = new Vector3(-0.92f, .31f, 0f);
        }
        else
        {
            state = MovementState.idle;
            canChangeDirection = true;
        }

        anim.SetInteger("state", (int)state);
    }
    private bool IsGrounded()
    {
        return Physics2D.BoxCast(coll.bounds.center, coll.bounds.size, 0f, Vector2.down, .1f, jumpableGround);
    }
}

probably your animator is not setup correctly

try reading this article:

imo you should change your logic and use

Animator.Play() instead of using transitions

1 Like

This was it, thanks for responding so fast. I had a transition from “Any State” to my attack animation, and when I just added individual transitions from each other animation to the attack one it started working as intended. I’ll definitely look into using Animator.Play as well, thanks for the suggestion!

1 Like