0
\$\begingroup\$

I got into a Unity-Tutorial and halfway-through I face this weird problem. I used this code so that my player may attack if he pressed a leftShift. When the player attacks, the animation starts playing in a loop - he never stops attacking and debugging show that attack is never false after the first "leftShift"-Input.

I removed the loops from the animator etc. - but that doesn't seem to be the problem because "attack" never get's to false anyways. I tried different approaches. If I set "attack = false" immediately after attacking, he doesn't attack at all.

Sorry for asking such a beginner question but I can't seem to find my error.

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

public class Player : MonoBehaviour
{
private Rigidbody2D myRigidbody;

[SerializeField]
private float movementSpeed;

private bool facingRight = true;

private Animator myAnimator;

private bool attack = false;

// Start is called before the first frame update
void Start()
{
    myRigidbody = GetComponent<Rigidbody2D>();
    myAnimator = GetComponent<Animator>();
}

void Update()
{
    HandleInput();
    Debug.Log(attack);

}

// Update is called once per frame

void FixedUpdate()
{
    float horizontal = Input.GetAxis("Horizontal");
    HandleMovement(horizontal);
    Flip(horizontal);
    HandleAttacks();
    ResetValues();


}

private void HandleMovement(float horizontal)
{
    if (!this.myAnimator.GetCurrentAnimatorStateInfo(0).IsTag("Attack"))
    {


        myRigidbody.velocity = new Vector2(horizontal * movementSpeed, myRigidbody.velocity.y);
        myAnimator.SetFloat("speed", Mathf.Abs(horizontal));
    }
}

private void HandleAttacks()
{
    if (attack)
    {
        myAnimator.SetTrigger("attack");


    } 
}

private void HandleInput()
{
    if (Input.GetKeyDown(KeyCode.LeftShift))
    {
        attack = true;

    }
    attack = false;
}

private void Flip(float horizontal)
{
    if(horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
    {
        facingRight = !facingRight;
        Vector3 theScale = transform.localScale;
        theScale.x *= -1;
        transform.localScale = theScale;
    }
}

private void ResetValues()
{
    attack = false;
}
}

IdleToAttack

AttackToIdle

Attack

Attack2

\$\endgroup\$
3
\$\begingroup\$

The issue was that only the bool "attack" was being changed, not the animation parameter "attack. After lots of testing this code finally works if anyone is interested:

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

public class Player : MonoBehaviour
{
    private Rigidbody2D myRigidbody;

    [SerializeField]
    private float movementSpeed;
    private bool attack = false;

    private float attackTimer;

    private bool facingRight = true;

    private Animator myAnimator;

    // Start is called before the first frame update 
    void Start()
    {
        myRigidbody = GetComponent<Rigidbody2D>();
        myAnimator = GetComponent<Animator>();
    }

    void Update()
    {
        HandleInput();
        if (attack)
        {
            Debug.Log(attack);
        }

        float horizontal = Input.GetAxis("Horizontal");

        HandleMovement(horizontal);
        Flip(horizontal);
        HandleAttacks();
        //ResetValues();

    }

    // Update is called once per frame 

    void FixedUpdate()
    {



    }

    private void HandleMovement(float horizontal)
    {
        if (!this.myAnimator.GetCurrentAnimatorStateInfo(0).IsTag("Attack"))
        {


            myRigidbody.velocity = new Vector2(horizontal * movementSpeed, myRigidbody.velocity.y);
            myAnimator.SetFloat("speed", Mathf.Abs(horizontal));
        }
    }

    private void HandleAttacks()
    {
        if (attack)
        {
            myAnimator.SetTrigger("attack");

            attack = false;
            myAnimator.ResetTrigger("attack");

        }
    }

    private void HandleInput()
    {
        if (Input.GetKeyDown(KeyCode.LeftShift))
        {

            attack = true;
            HandleAttacks();

        }

    }

    private void Flip(float horizontal)
    {
        if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
        {
            facingRight = !facingRight;
            Vector3 theScale = transform.localScale;
            theScale.x *= -1;
            transform.localScale = theScale;
        }
    }

    private void ResetValues()
    {
        attack = false;
    }

}
\$\endgroup\$
  • \$\begingroup\$ Hey Jeff, thanks for your answer and sorry again for this beginner question. First I tried to do as you told me which didn't work. Then I copied your code and replaced mine with yours. The result is the same; the attack keeps looping. Although the debug doesn't get cluttered anymore - thank you for that :D I suppose I could make pictures of my animator settings - am I allowed to post Imgur-links here? \$\endgroup\$ – Redgrieve Jan 6 at 22:28
  • \$\begingroup\$ Yes you're allowed, just edit your question and insert an image. \$\endgroup\$ – JeffBrin Jan 6 at 22:30
  • \$\begingroup\$ Thanks for the advice; I think these 3 pictures are the important ones. Please don't find any error there; that would be emberassing >.> \$\endgroup\$ – Redgrieve Jan 6 at 22:44
  • \$\begingroup\$ Maybe try adding a condition to Attack -> IdleAnimation where attack needs to be false? Or maybe when you imported your Attack animation you accidentally checked looping to true. \$\endgroup\$ – JeffBrin Jan 6 at 23:20
  • \$\begingroup\$ Done that;problem is that he then attacks once and doesn't go back to idle because attack is never false again. In the last picture it shows my import without "loop" selected. Edit: Problem is that attack, once it's true, it stay's true. That's what debug shows too. \$\endgroup\$ – Redgrieve Jan 6 at 23:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.