Something keeps setting canAtk to false.

So I am working on a SCP game, and this enemy object cannot attack because something keeps setting canAtk to false, and sometimes it don’t and doesn’t set it to true. I do not know what is causing this, my unity has been crashing frequently lately, I don’t know if this relates to this issue.

using System.Collections;
using UnityEngine;

public class SCP173 : MonoBehaviour
{
    public float speed;

    public CharacterController controller;
    public Player player;

    public float gravity;

    public LayerMask LayersToDetect;

    private bool atkDelay;
    [SerializeField]
    private bool canAtk;

    private AudioSource sound;

    [SerializeField]
    private AudioClip[] soundlist;

    [HideInInspector]
    public GameObject Target;

    public int visionMeter;

    private void Awake()
    {
        sound = GetComponent<AudioSource>();
    }

    private void Update()
    {
        if (visionMeter >= 1)
            return;

        Invoke("DoAttack", 0.1f);
    }

    void DoAttack()
    {
        if (Target == null)
        {
            player = GameObject.Find("Player").GetComponent<Player>();
            StartCoroutine(Attack(player.gameObject));
        }
        else
        {
            StartCoroutine(Attack(Target));
        }
    }

    public IEnumerator Attack(GameObject target)
    {
        if (target == null)
        {
            target = player.gameObject;
        }

        FaceTarget(target.transform.position);
        controller.Move(transform.forward * speed * Time.deltaTime);

        Ray frontRay = new Ray();
        RaycastHit hit;

        frontRay.origin = new Vector3(transform.position.x, transform.position.y + 1f, transform.position.z);
        frontRay.direction = transform.forward;

        Vector3 foward = transform.TransformDirection(Vector3.forward) * 10;

        if (Physics.Raycast(frontRay, out hit, 1f, LayersToDetect))
        {
            if (hit.collider.gameObject.tag != "NPC" || hit.collider.gameObject.tag != "Player")
            {
                canAtk = false;
                Debug.Log(canAtk);
            }

            if (hit.collider.gameObject.tag == "NPC" || hit.collider.gameObject.tag == "Player")
            {
                canAtk = true;
                Debug.Log(canAtk);
            }
        }

        if (atkDelay == false && canAtk == true)
        {
            if (target.tag == "NPC")
            {
                target.GetComponent<NPC>().TakeDamage(10000f);
                sound.clip = soundlist[Random.Range(0, soundlist.Length)];
                sound.Play();
                atkDelay = true;
                yield return new WaitForSeconds(0.5f);
                atkDelay = false;
            }
            if (target.tag == "Player")
            {
                target.GetComponent<Player>().TakeDamage(10000f);
                sound.clip = soundlist[Random.Range(0, soundlist.Length)];
                sound.Play();
                atkDelay = true;
                yield return new WaitForSeconds(0.5f);
                atkDelay = false;
            }
        }
    }

    private void OnTriggerStay(Collider other)
    {
        if(other.gameObject.tag == "NPC")
        {
            Target = other.gameObject;
        }
    }

    private void FaceTarget(Vector3 destination)
    {
        Vector3 lookPos = destination;
        lookPos.y = transform.position.y;
        transform.LookAt(lookPos);
    }
}

This really could be anything, so kinda hard to say from here staring at the code.

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run?
  • what are the values of the variables involved? Are they initialized?

Knowing this information will help you reason about the behavior you are seeing.