Enemy AI does not detect me

I have an issue with my script.The enemy is supposed to walk towards you when you get into his range and if you are close enough, the enemy will attack.The problem is, the enemy is not doing anything at all.I checked my script and cannot see the issue.Tried some Debug.Log messages to see something and everything seems to be fine.I dont even get any script errors.Is there something i missed?

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

public class EnemyBehaviour : MonoBehaviour,IDamegable
{
    public int Health { get; set; }
    private float staggerTime;
    public float startStaggerTime;

    [SerializeField]
    protected float health;

    #region Public Properties
    public Transform rayCast;
    public LayerMask raycastMask;
    public float rayCastLenght;
    public float attackDistance; //minimum distance for attack;
    public float movespeed;
    public float timer; //Delay between attacks
    #endregion

    #region Private Properties
    private RaycastHit2D hit;
    private GameObject target;
    private Animator anim;
    private float distance; //distance between player and enemy
    private bool attackMode;
    private bool inRange; //if in range
    private bool cooling; //enemy cooldown after attack;
    private float intTimer;
    #endregion



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

    private void Update()
    {

        if (inRange)
        {
            hit = Physics2D.Raycast(rayCast.position, Vector3.left, rayCastLenght, raycastMask);
            RaycastDebugger();
        }

        //when Player Is Detected
        if (hit.collider != null)
        {
            EnemyLogic();
        }
        else if (hit.collider == null)
        {
            inRange = false;
        }

        if (inRange == false)
        {
            anim.SetBool("CanWalk", false);
            StopAttack();
        }

        #region Stagger
        if (staggerTime <= 0)
        {
            //normal speed
        }
        else
        {
            //speed 0
            staggerTime -= Time.deltaTime;
        }
        #endregion
    }

    void OnTriggerEnter2D(Collider2D trig)
    {
        if (trig.gameObject.tag == "Player")
        {
            target = trig.gameObject;
            inRange = true;
        }
    }

    void EnemyLogic()
    {
        distance = Vector2.Distance(transform.position, target.transform.position);
        if (distance > attackDistance)
        {
            Move();
            StopAttack();
        }
        else if (attackDistance >= distance && cooling == false)
        {
            Attack();
        }

        if (cooling)
        {
            Cooldown();
            anim.SetBool("Attack", false);
        }
    }

    void Move()
    {
        anim.SetBool("CanWalk", true);
        if (!anim.GetCurrentAnimatorStateInfo(0).IsName("Enemy_Attack"))
        {
            Vector2 targetPosition = new Vector3(target.transform.position.x, transform.position.y);
            transform.position = Vector3.MoveTowards(transform.position, targetPosition, movespeed * Time.deltaTime);
        }
    }

    void Attack()
    {
        timer = intTimer;
        attackMode = true;
        anim.SetBool("CanWalk", false);
        anim.SetBool("Attack", true);
        Debug.Log("ATTACKING");
    }

    void StopAttack()
    {
        cooling = false;
        attackMode = false;
        anim.SetBool("Attack", false);
    }

    public void RaycastDebugger()
    {
        if (distance > attackDistance)
        {
            Debug.DrawRay(rayCast.position, Vector3.left * rayCastLenght, Color.red);
        }
        else if (attackDistance > distance)
        {
            Debug.DrawRay(rayCast.position, Vector3.left * rayCastLenght, Color.green);
        }
    }

    public void TriggerCooling()
    {
        cooling = true;
    }

    void Cooldown()
    {
        timer -= Time.deltaTime;
        if (timer <= 0 && cooling && attackMode)
        {
            cooling = false;
            timer = intTimer;
        }
    }

    public void Damage(float damage)
    {
        health -= damage;
        staggerTime = startStaggerTime;
        Debug.Log("Took damage");

        if (health <= 0)
        {
            Destroy(gameObject);
            Debug.Log("Died");
        }
    }
}

What do you mean by this? Did inRange get set to true or not? Is it true and he’s still not going towards you? Did it get set to true and then returned to false? What happens if you ALWAYS set it to true? etc.etc.etc. Just standard debugging!!

Get seriously busy with those Debug.Log() calls… figure out what’s going on.

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is
  • you’re getting an error or warning and you haven’t noticed it in the console window

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 order does it run in?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

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

If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

https://discussions.unity.com/t/839300/3

You must find a way to get the information you need in order to reason about what the problem is.

After Filling the code with debug messages,Console gets filled with log message that is called from function StopAttack(); and from Update() function statement

       else if (hit.collider == null)
        {
            inRange = false;
            Debug.Log("InRangeFalse");
        }
        else if (hit.collider == null)
        {
            inRange = false;
            Debug.Log("HitCollider == null");
        }

So if, you put a Debug.Log inside an if block like this:

if (inRange)
        {   Debug.Log(" Player is in Range ");
            hit = Physics2D.Raycast(rayCast.position, Vector3.left, rayCastLenght, raycastMask);
            RaycastDebugger();
        }

and then when you run your game and you don’t ever see the message output to the console, that means that inRange is probably never true.

if you write

Debug.Log ("The value of inRange is ["+inRange+"]");
if (inRange)
        {   Debug.Log(" Player is in Range ");
            hit = Physics2D.Raycast(rayCast.position, Vector3.left, rayCastLenght, raycastMask);
            RaycastDebugger();
        }

You can see the value for yourself. If you try this and you don’t see either message, then make sure that the script is actually assigned to a GameObject in the current scene and that there are no errors in the console.

1 Like

After trying to implement the second method of the debug message i get: The Value of inRange is [False]