Enemy did not chase player when player get in it's range

i’ve followed all step but enemy did not chase player when player get in it’s range

Are there any errors in the Console window?

Paste in your AIController.cs script and we’ll take a look.

1 Like

no,there are no any errors in the console.i think it come from unity\

Paste in the text of your PlayerController.cs, Mover.cs and Fighter.cs, and we’ll take a look.
You can format these scripts by selecting the text after you’ve pasted them and pressing the </> button on the formatting bar.

1 Like
Paste in the text of your PlayerController.cs, Mover.cs and Fighter.cs, and we'll take a look.
You can format these scripts by selecting the text after you've pasted them and pressing the `</>` button on the formatting bar.
[/quote]

type or paste code here

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPG.Combat;
namespace RPG.Control
{
public class AIController:MonoBehaviour
{
        [SerializeField] float chaseDistance = 5f;
        Fighter fighter;
        GameObject player;
        private void Start()
        {
            fighter = GetComponent<Fighter>();
            player = GameObject.FindWithTag("Player");
        }
        private void Update()
        {
            
            if (InAttackRangeOfPlayer()&&fighter.canAttack(player))
            {
                fighter.Attack(player);
                print("shoud");
            } else
            {
                fighter.Cancel();
            }    
        }
        private bool InAttackRangeOfPlayer()
        {
            float distanceToPlayer = Vector3.Distance(player.transform.position, transform.position);
            return distanceToPlayer < chaseDistance;
        }    
 }

}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPG.Movement;
using System;
using RPG.Combat;

namespace RPG.Control
{
public class PlayerControl : MonoBehaviour
{

    private void Update()
        {
          if(InteractWithCombat())return;
            if(InteractWithMovement())return;
            //print("aaaaa");
        }

        private bool InteractWithCombat()
        { 
            RaycastHit[] hits = Physics.RaycastAll(getRay());
            foreach(RaycastHit hit in hits)
            {
            CombatTarget target=hit.transform.GetComponent<CombatTarget>();
                if (target == null) continue;
                GameObject targetGameObject=target.gameObject;
                if(!GetComponent<Fighter>().canAttack(targetGameObject))
                {
                    continue;
                }
               
                if (target == null) continue;
                if(Input.GetMouseButtonDown(0))
                {
                    GetComponent<Fighter>().Attack(targetGameObject);
                  
                }    
                return true;
            }  
            return false;
        }

        private bool InteractWithMovement()
        {
         
            RaycastHit hit;
            bool hasHit = Physics.Raycast(getRay(), out hit);
            if (hasHit)
            {
                if(Input.GetMouseButton(0))
                {
                GetComponent<Mover>().StartMoveAction(hit.point);

                }    
            return true;
            }
            return false;
        }

        private static Ray getRay()
        {
            return Camera.main.ScreenPointToRay(Input.mousePosition);
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPG.Movement;
using RPG.Core;


namespace RPG.Combat
{
    public class Fighter : MonoBehaviour,IAction
    
    {
       

        [SerializeField] float weaponRange = 3f;
        [SerializeField] float timeBetweenAttack = 1;
        float timeSinceLastAttack = 0;
        float weaponDamage = 5f;
       Health target;

       

        public void Cancel()
        {
            stopAttack();
            target = null;
        }

        private void stopAttack()
        {
            GetComponent<Animator>().SetTrigger("stopAttack");
            GetComponent<Animator>().ResetTrigger("attack");
        }

        void Update()
        {
            timeSinceLastAttack += Time.deltaTime;
            if (target == null) return;
            if (target.IsDead()) return;
           if (!getIsInRange())
            {
                GetComponent<Mover>().MoveTo(target.transform.position);
            }
            else
            {
                GetComponent<Mover>().Cancel();
                AttackBehaviour();
            }

        }

        private void AttackBehaviour()
        {
             transform.LookAt(target.transform);
            if(timeSinceLastAttack>timeBetweenAttack)
            {
                triggerAttack();
                timeSinceLastAttack = 0;
            }
        }

        private void triggerAttack()
        {
            GetComponent<Animator>().SetTrigger("attack");
            GetComponent<Animator>().ResetTrigger("stopAttack");
        }

        //Animation Event
        void Hit()
        {
            //Health healthComponent = target.GetComponent<Health>();
            if(target==null)
            {
                return;
            }
            target.TakeDamage(weaponDamage);
        }    

        private bool getIsInRange()
        {
            return Vector3.Distance(transform.position, target.transform.position) < weaponRange;
        }
        public bool canAttack(GameObject combatTarget)
        {
            if (combatTarget == null) {return false; }
            
            Health targetToTest = combatTarget.GetComponent<Health>();
            return targetToTest != null && !targetToTest.IsDead();
        }
        public void Attack(GameObject combatTarget)
        {
            GetComponent<ActionSchedule>().StartAction(this);
            target = combatTarget.GetComponent<Health>();
        }    
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using RPG.Core;
namespace RPG.Movement
{
    public class Mover : MonoBehaviour ,IAction
    {
        [SerializeField] Transform target;
        NavMeshAgent navMeshAgent;

        // Update is called once per frame
        private void Start()
        {
            navMeshAgent = GetComponent<NavMeshAgent>();
        }
        void Update()
        {

            UpdateAnimation();

        }

        public void StartMoveAction(Vector3 destination)
        {
            GetComponent<ActionSchedule>().StartAction(this);
            MoveTo(destination);
        }    
        public void MoveTo(Vector3 destination)
        {
            navMeshAgent.destination = destination;
            navMeshAgent.isStopped = false;
        }
        public void Cancel()

        {
            navMeshAgent.isStopped = true;
        }    
        private void UpdateAnimation()
        {
            Vector3 velocity = navMeshAgent.velocity;
            Vector3 localVelocity = transform.InverseTransformDirection(velocity);
            float speed = localVelocity.z;
            GetComponent<Animator>().SetFloat("forwardSpeed", speed);
        }



    }
}

add this line just before the return statement of AIController.InAttackRangeOfPlayer:

Debug.Log($"{name} is {distanceToPlayer} units from player.  Chase Distance is {chaseDistance}, InAttackRangeOfPlayer = {distanceToPlayer<chaseDistance}");

here’re the result

One more thing to look at, the ActionScheduler

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

namespace RPG.Core
{
    public class ActionSchedule : MonoBehaviour
    {
        IAction currenAction;

        // Update is called once per frame
      public void StartAction(IAction action)
            {
            if (currenAction == action) return;
            if(currenAction != null)
            {
            currenAction.Cancel();

            }    
            currenAction = action; 
            }
    }

}

This might be a long shot, but did you update your terrain or made any changes to it? Maybe you forgot to update/bake the new navmesh and theres no path to your player.

Zip up your project and upload to https://gdev.tv/projectupload and I’ll take a closer look.
Be sure to remove the Library folder to conserve space.

i’ve followed all those step from lecture

i’ve uploaded my project. hope u can help me solve this error. Thanks

There were actually 3 identical null reference errors in the Console.

Your Enemies don’t have an ActionScheduler. The null references were in Fighter’s Attack() method

GetComponent<ActionScheduler>().StartAction(this);

Since there was no ActionScheduler attached to the enemy, this caused the null reference, at which point the rest of the method never runs, and the target is not set.

There is also no Health component on the player, so when you get past the ActionScheduler line, a Health is not found and target will still be null.

2 Likes

i’ve just added ActionScheduler to my enemies but they’re still not chase the player

Forgot the other issue, there is no Health component on your player.

1 Like

thank it’ve ran .Thank u so much