GetComponent from enemy script to player script sometimes works

Hello. Well, this is a long one.

So I’m making my first game, and I’m in the process of making enemy AI, and I had all set up for the movement of the enemies. Before that, I had made the attacking (player → enemy) script and animations - using attack points and collision detection - and it worked just fine. But now the Attack() function I made for the player sometimes works and other don’t (I get a NullReferenceException Error everytime I hit the enemy), apparently It is an error with the GetComponent that brings the enemy script to the player script. Also, I copied a couple of enemies and tried to hit them; the funny thing is, some of them register the attack, other don’t, and this seems to be random, because when I restart Unity I can hit some other enemies and other don’t (whereas in previous attempts I could hit 'em). I sincerely don’t know what I did wrong, because I haven’t touched that function since I made it, and its halting my progress. I’d love to get some help with this :frowning:

The Attack() function:

private void Attack()
        {
            //This indicates that, if the player is being hurt or is falling, he can't perform an attack.
            if(!Animator.GetCurrentAnimatorStateInfo(0).IsTag("5") || !Animator.GetCurrentAnimatorStateInfo(0).IsTag("4"))
            {
                Debug.Log("Enemy damaged");
                Animator.SetTrigger("Attack");
    
                Collider2D[] HitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, AttackRange, EnemyLayers);
                foreach(Collider2D Enemy in HitEnemies)
                {
                 //This is precisely where the error occurs. As far as I know, there's nothing wrong with this, and I have everything labelled correctly.   
                 Enemy.GetComponent<EnemyScript>().TakeDamage(AttackDamage);
                }
            }
        }

The Enemy TakeDamage() function:

    public void TakeDamage(int Damage)
    {
        Debug.Log("Enemy recieved damage");
        CurrentHealth -= Damage;

        Animator.SetTrigger("Hurt");

        if(CurrentHealth <= 0)
        {
            Die();
        }
    }

For the whole context, the player script:

public class PlayerScript: MonoBehaviour
{
    public float Speed = 3.5f;
    public float JumpForce;

    public Transform AttackPoint;
    public LayerMask EnemyLayers; 
    private int ColliderDamage = 6;

    public float AttackRange = 0.5f;
    public int AttackDamage = 20; 

    private Rigidbody2D Rigidbody2D;
    private Animator Animator;
    private float Horizontal;
    private bool Grounded;

    public float KnockBack;
    public float KnockBackLength;
    public float KnockBackCount;
    public bool KnockFromRight;

    private void Start()
    {
        Rigidbody2D = GetComponent<Rigidbody2D>();
        Animator = GetComponent<Animator>();
    }

    private void OnCollisionEnter2D(Collision2D Collision)
    {
      if (Collision.gameObject.tag == "Enemy" || Collision.gameObject.tag == "Hazard")
      {
        Debug.Log("Collider Damage Taken");
        TakeEnemyDamage(ColliderDamage);
      }
    }

    private void Update()
    {
        if(Animator.GetCurrentAnimatorStateInfo(0).IsTag("2"))
        {
            Speed = 0.0f;
            return;
        } else {
            Speed = 3.5f;
        }

        if(Animator.GetCurrentAnimatorStateInfo(0).IsTag("4"))
        {
            Speed = 0.0f;

            return;
        } else {
            Speed = 3.5f;
        }

        if(Animator.GetCurrentAnimatorStateInfo(0).IsTag("5"))
        {
            Speed = 0.0f;

            return;
        } else {
            Speed = 3.5f;
        }

        Animator.SetFloat("YVelocity", Rigidbody2D.velocity.y);

        Horizontal = Input.GetAxisRaw("Horizontal");

        if (Horizontal < 0.0f) transform.localScale = new Vector3(-1.0f, 1.0f, 1.0f);
        else if (Horizontal > 0.0f) transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);

        Animator.SetBool("Run", Horizontal != 0.0f);
        Debug.DrawRay(transform.position, Vector3.down * 0.5f, Color.red);
        if (Physics2D.Raycast(transform.position, Vector3.down, 0.5f))
        {
            Grounded = true;
        }
        else Grounded = false;
        Animator.SetBool("Jumping", !Grounded);

        if (Input.GetKeyDown(KeyCode.Space) && Grounded)
        {
            Jump();
            Animator.SetBool("Jumping", true);
        }

       //Here's the call to the attack function. It works fine.
        if (Input.GetKeyDown(KeyCode.F))
        {
            Attack();
        }

    }

    private void Jump()
    {
        Rigidbody2D.AddForce(Vector2.up * JumpForce);
    }
    
    *//This is where the error appears.
    private void Attack()
    {
        //This indicates that, if the player is being hurt or is falling, he can't perform an attack.
        if(!Animator.GetCurrentAnimatorStateInfo(0).IsTag("5") || !Animator.GetCurrentAnimatorStateInfo(0).IsTag("4"))
        {
            Debug.Log("Enemy damaged");
            Animator.SetTrigger("Attack");

            Collider2D[] HitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, AttackRange, EnemyLayers);
            foreach(Collider2D Enemy in HitEnemies)
            {
             //This is precisely where the error occurs. As far as I know, there's nothing wrong with this, and I have everything labelled correctly.   Enemy.GetComponent<EnemyScript>().TakeDamage(AttackDamage);
            }
        }
    }*

    void OnDrawGizmosSelected()
    {
        if(AttackPoint == null)
            return;
        Gizmos.DrawWireSphere(AttackPoint.position, AttackRange);
    }   

    private void FixedUpdate()
    {
        Rigidbody2D.velocity = new Vector2(Horizontal * Speed, Rigidbody2D.velocity.y);
    }
}

And the whole Enemy Script:

public class EnemyScript : MonoBehaviour
{
    public Animator Animator;
    public LayerMask PlayerLayers;

    public bool PlayerInArea 
    {
        get;
        private set;
    }
    public Transform Player 
    {
        get;
        private set;
    }

    private string DetectionTag = "Player";

    public int MaxHealth = 80;
    int CurrentHealth;

    void Awake()
    {
        Animator = GetComponent<Animator>();
    }

    void Start()
    {
        CurrentHealth = MaxHealth;    
    }

    public void TakeDamage(int Damage)
    {
        Debug.Log("Enemy recieved damage");
        CurrentHealth -= Damage;

        Animator.SetTrigger("Hurt");

        if(CurrentHealth <= 0)
        {
            Die();
        }
    }

    void Die()
    {
        Debug.Log("Enemy Died");

        Animator.SetBool("Death", true);

        GetComponent<Collider2D>().enabled = false;
    }

    private void OnTriggerEnter2D(Collider2D Other)
    {
        if(Other.gameObject.tag == "Player")
        {
            var PlayerAp = Other.gameObject.GetComponent<PlayerScript>();

            if(Other.transform.position.x < transform.position.x)
            {
                PlayerAp.KnockFromRight = true;
            } else 
            {
                PlayerAp.KnockFromRight = false;
            }

            if(Other.CompareTag(DetectionTag))
            {
                Debug.Log("Player in enemy area");
                PlayerInArea = true;
                Player = Other.gameObject.transform;
            }
        }
    }   

    private void OnTriggerExit2D(Collider2D Other)
    {
        if(Other.CompareTag(DetectionTag))
        {
            Debug.Log("Player exiting enemy area");
            PlayerInArea = false;
            Player = null;
        }
    }

}

So if im to understand, your saying GetComponent sometimes doesnt work? the only thing i can think of that would cause this is if the script was on a different object than the animator. If were talking about it detecting a collision triggered event you can increase the quality of your collisions to help. but youll be able to see within the first frame if everything is where its supposed to be, Since GetComponent runs in the Start function its only called once right when it becomes active. It be nice to know which line is giving you an error, but id be willing to guess the issue is starting in line of code

if(!Animator.GetCurrentAnimatorStateInfo(0).IsTag(“5”) || !Animator.GetCurrentAnimatorStateInfo(0).IsTag(“4”))

I would seperate this function, so you just have an straight attack function that gets called IF it meets the requirements. cause right now its basically like you tell it to attack but then after tell it to wait to see who it is, which seems convoluted and prone to issue.