Animation wont Work

I have a Bug that my Console wont Show. The Attack Animation plays but then stops at the last sprite and then doesn`t go back to the previous Animation.

Attack Code:

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

public class Attack : MonoBehaviour
{
	public Transform attackPos;
	public LayerMask enemies;
	public float attackrange;
	public int damage;
	private Animator anim;
	private int wechsel;
	// Start is called before the first frame update
	void Start()
	{
		anim = GetComponent<Animator>();
		wechsel = PlayerPrefs.GetInt("wechsel", 0);
	}

	// Update is called once per frame
	void Update()
	{
		if (Input.GetMouseButtonDown(0))
		{
				anim.SetBool("isAttacking", true);

			FindObjectOfType<AudioManager>().Play("Sword");
			Collider2D[] enemiesToDamage = Physics2D.OverlapCircleAll(attackPos.position, attackrange, enemies);
			for (int i = 0; i < enemiesToDamage.Length; i++)
			{
				enemiesToDamage[i].GetComponent<Enemy>().health -= damage;
			}
		}
	}
	private void OnDrawGizmosSelected()
	{
		Gizmos.color = Color.red;
		Gizmos.DrawWireSphere(attackPos.position, attackrange);
	}
}

Aufhoren Code:

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

public class aufhoren : StateMachineBehaviour
{
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    //override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.SetBool("IsAttacking", false);
    }

    // OnStateMove is called right after Animator.OnAnimatorMove()
    //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that processes and affects root motion
    //}

    // OnStateIK is called right after Animator.OnAnimatorIK()
    //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that sets up animation IK (inverse kinematics)
    //}
}

Sounds like you wrote a bug… and that means… time to start debugging!

By debugging you can find out exactly what your program is doing so you can fix it.

Anything with Animations / Animators / Mechanim:

Only consider the code AFTER you have done this critical step:

Always start with the Animator state machine and prove it works in isolation, no code at all.

Here’s more reading:

Once the animator works perfect, move onto debugging the code:

Use the above techniques to get the information you need in order to reason about what the problem is.

You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

Remember with Unity the code is only a tiny fraction of the problem space. Everything asset- and scene- wise must also be set up correctly to match the associated code and its assumptions.

I did today and now it wont show again but the script is correct

heres the new script i use:

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

public class Attack : MonoBehaviour
{
	public Transform attackPos;
	public LayerMask enemies;
	public float attackRange;
	public int damage;
	private Animator anim;
	private int wechsel;
	private bool isAttacking = false;

	void Start()
	{
		anim = GetComponent<Animator>();
		wechsel = PlayerPrefs.GetInt("wechsel", 0);
	}

	void Update()
	{
		if (Input.GetMouseButtonDown(0) && !isAttacking)
		{
			StartCoroutine(AttackCoroutine());
		}
	}

	private IEnumerator AttackCoroutine()
	{
		isAttacking = true;

		// Angriffsanimation basierend auf dem `wechsel`-Wert starten
		switch (wechsel)
		{
			case 1:
				Debug.Log("Setting isAttacking_iron to true");
				anim.SetBool("isAttacking_iron", true);
				yield return new WaitForSeconds(0.5f);
				anim.SetBool("isAttacking_iron", false);
				Debug.Log("Setting isAttacking_iron to false");
				break;
			case 2:
				Debug.Log("Setting isAttacking_dia to true");
				anim.SetBool("isAttacking_dia", true);
				yield return new WaitForSeconds(0.5f);
				anim.SetBool("isAttacking_dia", false);
				Debug.Log("Setting isAttacking_dia to false");
				break;
			case 3:
				Debug.Log("Setting isAttacking_black to true");
				anim.SetBool("isAttacking_black", true);
				yield return new WaitForSeconds(0.5f);
				anim.SetBool("isAttacking_black", false);
				Debug.Log("Setting isAttacking_black to false");
				break;
			case 4:
				Debug.Log("Setting isAttacking to true");
				anim.SetBool("isAttacking", true);
				yield return new WaitForSeconds(0.5f);
				anim.SetBool("isAttacking", false);
				Debug.Log("Setting isAttacking to false");
				break;
		}

		// Sound und Schaden anwenden
		FindObjectOfType<AudioManager>().Play("Sword");
		Collider2D[] enemiesToDamage = Physics2D.OverlapCircleAll(attackPos.position, attackRange, enemies);
		for (int i = 0; i < enemiesToDamage.Length; i++)
		{
			enemiesToDamage[i].GetComponent<Enemy>().TakeDamage(damage);
		}

		isAttacking = false;
	}

	private void OnDrawGizmosSelected()
	{
		Gizmos.color = Color.red;
		Gizmos.DrawWireSphere(attackPos.position, attackRange);
	}
}

The debug and add logging reply is what I also allways do. Another thing you could do is add some more prechecks. For example:

for (int i = 0; i < enemiesToDamage.Length; i++)
{
       // check whether it has an Enemy component
	enemiesToDamage[i].GetComponent<Enemy>()?.TakeDamage(damage);
}

Next, make a seperate function to set a specific bool temporarly to true and back to false

switch (wechsel) case 1: yield return TempAnimate("isAttacking_iron", 0.5f) ...
private IEnumerator TempAnimate(string setting, float time = 0.5f){
...
}

Next, simplify, you have 4 states, try to test it first with one simpler state…