Hey everyone I’m having a problem with my navmesh object following the player and randomly stopping in the a small radius around the same spot (theres a random spot with nothing there and if the agent goes within a radius of that spot it stops instantly)
I dont have any code that changes the agent to stop at the instace ( i do have a state machine that changes the agent to stop moving but that code isnt being called for when it gets to that spot)
I have no idea whats going on or why the aggent keeps stopping and i’ve been trying to figure this out for awhile and cant seem to get it. I’ll drop my code for the whole agent below.
P.s. the agent follows the player in the follow player state and looking at it in the inspector, when the agent stops its still in the follow player state and not switching to any other states (which would then make the agent stop moving)
using System.Collections;
using System.Collections.Generic;
using UnityEngine.AI;
using UnityEngine;
using EZCameraShake;
public class GhostsBehaviours : MonoBehaviour
{
private Animator anim;
private NavMeshAgent navmesh;
private GameObject player;
private AudioSource enemyAudio;
[SerializeField]
private List<AudioClip> audioClips;
private float audioClipOffset;
[SerializeField]
private Transform areaSpot;
[SerializeField]
private float areaSpotRadius;
[SerializeField]
private float areaSpotTimer;
[SerializeField]
private List<Transform> areaSpotsList;
[SerializeField]
private float patrolSpotTimer = 2;
[SerializeField]
private Material material;
[SerializeField]
private Camera playerCam;
[SerializeField]
private Transform creatureCamPos;
[SerializeField]
private Transform positionToLookAt;
public enum EnemyState
{
Patrol, FollowPlayer, Awake
}
[SerializeField]
private EnemyState _currentState;
private void Start()
{
areaSpotTimer = Random.Range(5, 15);
anim = GetComponent<Animator>();
navmesh = GetComponent<NavMeshAgent>();
player = GameObject.Find("Player");
enemyAudio = GetComponent<AudioSource>();
material.color = Color.white;
}
public void Update()
{
switch (_currentState)
{
case EnemyState.Awake:
AwakeState();
break;
case EnemyState.FollowPlayer:
FollowPlayerState();
break;
case EnemyState.Patrol:
PatrolState();
break;
}
}
private void AwakeState()
{
areaSpotTimer = Random.Range(7, 15);
}
private void FollowPlayerState()
{
float currentVal = anim.GetFloat("EnemyMovement");
if(player.GetComponent<PlayerMovement>().isControllable)
{
//if its within range of the area spot
if (Vector3.Distance(areaSpot.position, player.transform.position) < 130)
{
if (currentVal < 2)
{
anim.SetFloat("EnemyMovement", currentVal + (Time.deltaTime * 3f));
}
navmesh.speed = 15;
NavMeshPath path = new NavMeshPath();
navmesh.CalculatePath(player.transform.position, path);
if (player.transform.position != navmesh.destination)
{
navmesh.SetPath(path);
}
transform.SetParent(areaSpot);
}
//if its not within range
else
{
navmesh.speed = Mathf.Lerp(navmesh.speed, 4, Time.deltaTime * 1);
anim.SetFloat("EnemyMovement", currentVal - (Time.deltaTime));
patrolSpotTimer = 2;
if (navmesh.speed <= 7)
{
navmesh.SetDestination(transform.position);
_currentState = EnemyState.Patrol;
}
}
if (Vector3.Distance(transform.position, player.transform.position) <= navmesh.stoppingDistance)
{
player.GetComponent<PlayerMovement>().isControllable = false;
KillPlayer();
}
}
else
{
navmesh.SetDestination(transform.position);
_currentState = EnemyState.Patrol;
}
}
private void PatrolState()
{
//find new patrol spot
if(patrolSpotTimer > 0)
{
patrolSpotTimer -= Time.deltaTime;
if(patrolSpotTimer <= 0)
{
PatrolToNewSpots();
patrolSpotTimer = Random.Range(7, 15);
}
}
float currentval = anim.GetFloat("EnemyMovement");
if (navmesh.velocity.magnitude != 0)
{
if(currentval < 1)
{
anim.SetFloat("EnemyMovement", currentval + (Time.deltaTime * 2f));
}
}
else
{
if(currentval > 0)
{
anim.SetFloat("EnemyMovement", currentval - (Time.deltaTime * 2f));
}
}
//if the player is inside the boundaries
if (Vector3.Distance(areaSpot.position, player.transform.position) < areaSpotRadius)
{
if (areaSpotTimer > 0)
{
areaSpotTimer -= Time.deltaTime;
}
else if (areaSpotTimer <= 0)
{
ChangeMatColorWhenIrritated();
}
}
//if the player is NOT inside the boundaries
else
{
ChangeMatColorWhenCalmingDown();
}
GhostPatrolSounds();
}
private void KillPlayer()
{
playerCam.gameObject.GetComponent<CameraShaker>().enabled = false;
//moves the players camera onto the creature
playerCam.transform.parent = creatureCamPos;
playerCam.transform.position = creatureCamPos.position;
anim.SetTrigger("KillPlayer");
//enemyAudio.PlayOneShot(audioClips[1]);
var pausemenu = GameObject.Find("Canvas").GetComponent<PauseMenu>();
pausemenu.TurnOffFlashLight();
Invoke("BlackScreen", 1);
playerCam.transform.LookAt(positionToLookAt);
}
void ChangeMatColorWhenIrritated()
{
Color targetColor = new Color(.5f, 0, 0, 1);
if (material.color != targetColor)
{
material.color = Color.Lerp(material.color, targetColor, Time.deltaTime * 3);
}
else
{
navmesh.SetDestination(transform.position);
anim.SetTrigger("ChasePlayer");
_currentState = EnemyState.Awake;
}
}
void ChangeMatColorWhenCalmingDown()
{
Color currentColor = material.color;
if (material.color != Color.white)
{
material.color = Color.Lerp(currentColor, Color.white, Time.deltaTime * 3);
}
if(areaSpotTimer <= 0)
{
areaSpotTimer = Random.Range(5, 15);
}
}
public void FollowPlayerBool()
{
_currentState = EnemyState.FollowPlayer;
//navmesh.SetDestination(player.transform.position);
}
private void PatrolToNewSpots()
{
navmesh.speed = 4f;
for (int i = Random.Range(0, areaSpotsList.Count - 1); i < areaSpotsList.Count; i++)
{
if (areaSpotsList[i].childCount == 0)
{
navmesh.SetDestination(areaSpotsList[i].position);
transform.SetParent(areaSpotsList[i]);
return;
}
}
}
private void BlackScreen()
{
var pausemenu = GameObject.Find("Canvas").GetComponent<PauseMenu>();
pausemenu.BlackScreenEnabled();
}
private void GhostPatrolSounds()
{
if (audioClipOffset > 0)
{
audioClipOffset -= Time.deltaTime;
}
else
{
for (int i = Random.Range(0, audioClips.Count - 1); i < audioClips.Count; i++)
{
enemyAudio.pitch = Random.Range(.9f, 1.2f);
enemyAudio.PlayOneShot(audioClips[i]);
audioClipOffset = Random.Range(1, 3) + audioClips[i].length;
return;
}
}
}
private void GhostScreamClip(AudioClip clip)
{
enemyAudio.pitch = Random.Range(.5f, 1);
enemyAudio.PlayOneShot(clip, 2);
}
private void GhostSoundEffects(AudioClip clip)
{
enemyAudio.PlayOneShot(clip, 5f);
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(areaSpot.position, areaSpotRadius);
}
}
