The enemy is not chasing the player...😭

Hello, I am currently working on creating my own game. It’s my first time for coding with unity… I got some hardships working on this code error … I need help…

I have set up the enemy to wander around randomly when the player is not nearby, and to chase the player when the distance between them becomes shorter than a certain threshold. When the player moves away beyond a certain distance, the enemy stops chasing and resumes wandering.

After adding some additional features, I encountered an issue. The enemy no longer reacts when the player comes close, and when the player collides with the enemy, the enemy suddenly moves a certain distance away (remaining still while the player approaches!). Additionally, the enemy should be wandering when alone, but it only changes direction and does not move.

I’m not sure what part of the code is causing this issue. The Inspector settings appear to be correct.

There are no error signs in the editor, but when I resumed the game, the creature did not work…!!


Here is the codes :

Player code(firstpersoncontroller):

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UI;

public class FirstPersonController : MonoBehaviour

{

[SerializeField]

private float walkSpeed;

[SerializeField]

private float runSpeed;

[SerializeField]

private float applySpeed;

[SerializeField]

private float jumpForce;

[SerializeField]

private float maxStamina = 100f;

[SerializeField]

private float currentStamina;

[SerializeField]

private float staminaDrain = 10f;

[SerializeField]

private float staminaRecovery = 5f;

// Variable to check if there is enough stamina

private bool canRun = true;

private bool isWaitingToRun = false;

[SerializeField]

private float waitTime = 5f;

private float waitStartTime;

private bool isWalk = false;

private bool isRun = false;

private bool isGround = true;

// Fields related to sound

[SerializeField]

private AudioSource audioSource;

[SerializeField]

private AudioClip walkSound;

[SerializeField]

private AudioClip runSound;

[SerializeField]

private AudioClip staminaDepletedSound;

private CapsuleCollider capsuleCollider;

[SerializeField]

private float lookSensitivity;

[SerializeField]

private float cameraRotationLimit;

private float currentCameraRotationX = 0;

[SerializeField]

private Camera theCamera;

private Rigidbody myRigid;

[SerializeField]

private Image staminaBar;

[SerializeField]

private Color normalColor = Color.green;

[SerializeField]

private Color warningColor = Color.red;

void Start()

{

    capsuleCollider = GetComponent<CapsuleCollider>();

    myRigid = GetComponent<Rigidbody>();

    applySpeed = walkSpeed;

    currentStamina = maxStamina;

}

void Update()

{

    CheckIfGrounded();

    TryJump();

    TryRun();

    Move();

    RotateCamera();

    RotateCharacter();

    RecoverStamina();

    UpdateStaminaUI();

}

private void CheckIfGrounded()

{

    isGround = Physics.Raycast(transform.position, Vector3.down, capsuleCollider.bounds.extents.y + 0.1f);

}

private void TryJump()

{

    if (Input.GetKeyDown(KeyCode.Space) && isGround)

    {

        Jump();

    }

}

private void Jump()

{

    myRigid.velocity = transform.up * jumpForce;

}

private void TryRun()

{

    if (isWalk && Input.GetKey(KeyCode.LeftShift) && canRun)

    {

        Run();

        PlaySound(runSound);

    }

    else if (Input.GetKeyUp(KeyCode.LeftShift) || !canRun || !isWalk)

    {

        CancelRun();

        if (isWalk) PlaySound(walkSound);

        else audioSource.Stop();

    }

}

private void Run()

{

    if (currentStamina > 0)

    {

        isRun = true;

        applySpeed = runSpeed;

        currentStamina -= staminaDrain * Time.deltaTime;

        currentStamina = Mathf.Max(currentStamina, 0);

    }

    else

    {

        canRun = false;

        isWaitingToRun = true;

        waitStartTime = Time.time;

        PlaySound(staminaDepletedSound);

        CancelRun();

    }

}

private void CancelRun()

{

    isRun = false;

    applySpeed = walkSpeed;

}

private void RecoverStamina()

{

    if (!isRun && (currentStamina < maxStamina))

    {

        currentStamina += staminaRecovery * Time.deltaTime;

        currentStamina = Mathf.Min(currentStamina, maxStamina);

    }

    if ((currentStamina > 0) && isWaitingToRun && ((Time.time - waitStartTime) >= waitTime))

    {

        isWaitingToRun = false;

        canRun = true;

    }

}

private void UpdateStaminaUI()

{

    staminaBar.fillAmount = currentStamina / maxStamina;

    if (isWaitingToRun)

    {

        staminaBar.color = warningColor;

    }

    else

    {

        staminaBar.color = normalColor;

    }

}

private void PlaySound(AudioClip clip)

{

    if (audioSource.clip != clip || !audioSource.isPlaying)

    {

        audioSource.clip = clip;

        audioSource.Play();

    }

}

private void Move()

{

    float _moveDirX = Input.GetAxisRaw("Horizontal");

    float _moveDirZ = Input.GetAxisRaw("Vertical");

    if (_moveDirX != 0 || _moveDirZ != 0)

    {

        isWalk = true;

        if (!isRun && !audioSource.isPlaying) PlaySound(walkSound);

    }

    else

    {

        isWalk = false;

        audioSource.Stop();

    }

    Vector3 _moveHorizontal = transform.right * _moveDirX;

    Vector3 _moveVertical = transform.forward * _moveDirZ;

    Vector3 _velocity = (_moveHorizontal + _moveVertical).normalized * applySpeed;

    myRigid.MovePosition(transform.position + _velocity * Time.deltaTime);

}

private void RotateCharacter()

{

    float _yRotation = Input.GetAxis("Mouse X") * lookSensitivity;

    Vector3 _characterRotationY = new Vector3(0f, _yRotation, 0f);

    myRigid.MoveRotation(myRigid.rotation * Quaternion.Euler(_characterRotationY));

}

private void RotateCamera()

{

    float _xRotation = Input.GetAxis("Mouse Y") * lookSensitivity;

    currentCameraRotationX -= _xRotation;

    currentCameraRotationX = Mathf.Clamp(currentCameraRotationX, -cameraRotationLimit, cameraRotationLimit);

    theCamera.transform.localRotation = Quaternion.Euler(currentCameraRotationX, 0f, 0f);

}

}

---------------------------------------------enemy ai code:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.AI;

public class EnemyAI : MonoBehaviour

{

[SerializeField] Transform target;

[SerializeField] float chaseRange = 5f;            // Range for chasing the player

[SerializeField] float stopChasingRange = 10f;     // Distance to stop chasing

[SerializeField] float wanderRadius = 10f;         // Radius for random wandering

[SerializeField] float wanderTime = 5f;            // Time interval for moving to a random point

[SerializeField] float turnSpeed = 5f;

NavMeshAgent navMeshAgent;

float distanceToTarget = Mathf.Infinity;

bool isProvoked = false;

bool isWandering = false;

float wanderTimer;

void Start()

{

    navMeshAgent = GetComponent<NavMeshAgent>();

    wanderTimer = wanderTime;  // Set the timer for initial random movement

}

void Update()

{

    distanceToTarget = Vector3.Distance(target.position, transform.position);

    if (isProvoked)

    {

        EngageTarget();

    }

    else if (distanceToTarget <= chaseRange)

    {

        isProvoked = true;

    }

    else if (distanceToTarget >= stopChasingRange)

    {

        isProvoked = false;

        Wander();  // Stop chasing and start wandering

    }

}

private void EngageTarget()

{

    FaceTarget();

    if (distanceToTarget >= navMeshAgent.stoppingDistance)

    {

        ChaseTarget();

    }

    if (distanceToTarget <= navMeshAgent.stoppingDistance)

    {

        AttackTarget();

    }

    // Stop chasing if the target is too far away

    if (distanceToTarget >= stopChasingRange)

    {

        isProvoked = false;

        Wander();  // Wander randomly when the player is far away

    }

}

private void ChaseTarget()

{

    GetComponent<Animator>().SetBool("attack", false);

    GetComponent<Animator>().SetTrigger("move");

    navMeshAgent.SetDestination(target.position);

}

private void AttackTarget()

{

    GetComponent<Animator>().SetBool("attack", true);

}

private void FaceTarget()

{

    Vector3 direction = (target.position - transform.position).normalized;

    Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));

    transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * turnSpeed);

}

private void Wander()

{

    // Move to a random point at regular intervals

    wanderTimer += Time.deltaTime;

    if (wanderTimer >= wanderTime)

    {

        Vector3 newPos = RandomNavSphere(transform.position, wanderRadius, -1);

        navMeshAgent.SetDestination(newPos);

        wanderTimer = 0f;  // Reset timer

    }

}

// Find a random point

public static Vector3 RandomNavSphere(Vector3 origin, float dist, int layermask)

{

    Vector3 randomDirection = Random.insideUnitSphere * dist;

    randomDirection += origin;

    NavMeshHit navHit;

    NavMesh.SamplePosition(randomDirection, out navHit, dist, layermask);

    return navHit.position;

}

}

That just 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.

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.

Thank you so much for your response !!
I’ll check if there are any errors using debugging !! :smile:

By the way, if there are no issues in the code, are there any other inspectors I should check? I have set up the NavMeshAgent on the creature and baked the navigable space. The ground has also been marked as static. Of course, the scripts have been applied. I also set up the Mesh Renderer, Capsule Collider, and Capsule (Mesh Filter). I added animations to the Animator’s controller to move during attacks. I didn’t put anything in the Animator’s avatar, though (the creature is still a capsule, but this was never an issue before and the game ran fine).

From what I can see, the player doesn’t seem to be the issue. The creature isn’t able to perform ā€œwanderingā€ and ā€œstopping wandering to chase the player when they enter a certain range,ā€ or ā€œstopping the chase and resuming wandering when the player leaves a certain distance.ā€

I decorated the field using other assets, but only used prefabs, so nothing was specifically added to the inspector, aside from the script for closing doors.

Are there any other aspects of Unity editing, besides the creature’s inspector or script, that could affect the creature?

All the parts that go into making a navmesh guy behave.

Unity’s tutorials and/or manual are a great place to get this info in an up-to-date form.