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);
}
}