the erorr is “GetRemainingDistance” can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.StackTraceUtility:ExtractStackTrace ()
/**************************************************
- Last edit: 14/8/2024
*************************************************/
using UnityEngine;
using System.Collections;
using UnityEngine.Events;
using UnityEngine.AI;
using System.Collections.Generic;
[RequireComponent (typeof (AudioSource))]
public class Enemy : MonoBehaviour {
public float life = 100f;
public AudioClip hurtSound;
public AudioClip dieSound;
public float traceDistance = 10;
public float attackDistance = 2f;
public float sight = 6;
public float sightHeight = 1.6f;
public float FOV = 160;
[Space(10)]
[Header("Die Settings")]
public bool removeOnDead = false;
public float dieDelay = 5f;
public GameObject dieFX;
public float dieFXDelay = 0;
public UnityEvent DieEvent;
[Space(10)]
[Header("Patrol Settings")]
public bool patrol = false;
public GameObject patrolPoints;
private List<Transform> patrolPoint;
private int destPoint = 0;
float minTraceDistance;
float hitTrace = 0;
bool insight = false;
AudioSource AS;
Animator anim;
bool dead;
float distance;
NavMeshAgent NM;
Transform Player;
private MoneyManager moneyManager;
void Start () {
minTraceDistance = traceDistance;
insight = false;
NM = GetComponent<NavMeshAgent>();
Player = GameObject.FindWithTag("Player").transform;
AS = GetComponent<AudioSource>();
anim = GetComponent<Animator>();
dead = false;
NM.enabled = false;
NM.updatePosition = false;
moneyManager = FindObjectOfType<MoneyManager>();
if (moneyManager == null)
{
Debug.LogError("MoneyManager not found in the scene!");
}
if (patrolPoints) {
patrolPoint = new List<Transform>(patrolPoints.GetComponentsInChildren<Transform>());
patrolPoint.RemoveAt(0);
NM.enabled = true;
GotoNextPoint ();
}
}
void Update () {
if (!dead) {
distance = Vector3.Distance (transform.position, Player.position);
if (distance < sight) {
Vector3 direction = Player.transform.position - transform.position;
direction.y = 0;
float angle = Vector3.Angle(direction, transform.forward);
if (angle < FOV * 0.5f)
{
Ray sightRay = new Ray(transform.position + Vector3.up * sightHeight, direction);
RaycastHit hit;
if (Physics.Raycast(sightRay, out hit, sight))
{
if (hit.transform.CompareTag("Player"))
{
Debug.DrawRay(sightRay.origin, direction, Color.green);
insight = true;
} else
Debug.DrawRay(sightRay.origin, direction, Color.red);
}
}
}
if (insight) {
if (distance > traceDistance) {
insight = false;
}
}
if (distance <= attackDistance && !PlayerLife.dead && insight) {
NM.enabled = false;
Vector3 temPos = Player.position;
temPos.y = transform.position.y;
transform.LookAt(temPos);
anim.SetTrigger("attack");
} else if (distance <= traceDistance && !PlayerLife.dead && insight) {
NM.enabled = true;
NM.SetDestination (Player.position);
anim.SetTrigger("run");
if (patrol) anim.ResetTrigger("patrol");
} else {
if (patrol) {
NM.enabled = true;
anim.SetTrigger ("patrol");
if (NM.remainingDistance < 1f)
GotoNextPoint ();
} else {
NM.enabled = false;
anim.SetTrigger ("idle");
}
}
}
if (hitTrace > 0)
hitTrace -= Time.deltaTime;
if (hitTrace < 0) {
traceDistance = minTraceDistance;
hitTrace = 0;
}
}
void ImHit (string[] bulletInfo) {
if (!dead) {
if (hurtSound != null) {
AS.pitch = Random.Range (0.7f, 1.3f);
AS.PlayOneShot(hurtSound);
}
life -= float.Parse(bulletInfo[1]);
traceDistance = 100;
hitTrace = 5;
insight = true;
if (patrol) anim.ResetTrigger("patrol");
if (life <= 0) {
dead = true;
NM.enabled = false;
DieEvent.Invoke ();
if (anim)
anim.SetTrigger("die");
AS.pitch = 1;
AS.PlayOneShot(dieSound);
if (moneyManager != null)
{
moneyManager.OnEnemyKilled();
}
if (removeOnDead)
{
Destroy(gameObject, dieDelay);
}
if (dieFX)
Invoke ("ShowFX", dieFXDelay);
EnemyAttack[] EA = GetComponentsInChildren<EnemyAttack>();
foreach (var _EA in EA)
_EA.enabled = false;
}
}
}
void ShowFX () {
Instantiate(dieFX, transform.position, Quaternion.identity);
}
void GotoNextPoint() {
if (patrolPoint.Count == 0)
return;
NM.destination = patrolPoint[destPoint].position;
destPoint = (destPoint + 1) % patrolPoint.Count;
}
public void Patrol(bool doPatrol)
{
patrol = doPatrol;
}
void LateUpdate () {
NM.nextPosition = transform.position;
anim.ResetTrigger("idle");
anim.ResetTrigger("attack");
anim.ResetTrigger("run");
}
void OnAnimatorMove () {
Vector3 position = anim.rootPosition;
position.y = NM.nextPosition.y;
transform.position = position;
}
}