Hi.
I’m currently developing a dungeon crawler game and I’m stuck with a problem.
I have 2 scripts for the enemies, one for them to do a patrol and the other to chace the player when this one is spotted. The thing is the scripts are interfering with each other giving a weird behaviour. I was trying to keep them seperated without mixing both.
Anyone have any suggestion?
//Enemy patrol
[DefaultExecutionOrder(-100)]
public class EnemySimplePatrol : MonoBehaviour
{
//Dictates wheter the agent waits on each node.
[SerializeField]
bool _patrolWaiting;
//The total time we wait at each node.
[SerializeField]
float _totalWaitingTime = 3f;
//The probability of switching direction.
[SerializeField]
float _switchProbability = 0.2f;
//The list of all patrol nodes to visil.
[SerializeField]
List<Waypoint> _patrolPoints;
//Private variables for base behavior
NavMeshAgent _navMeshAgent;
Animator anim;
int _currentPatrolIndex;
bool _travelling;
bool _waiting;
bool _patrolForward;
float _waitTimer;
public void Start()
{
_navMeshAgent = this.GetComponent<NavMeshAgent>();
anim = GetComponent<Animator>();
if (_navMeshAgent == null)
{
Debug.LogError("not attached to " + gameObject.name);
}
else
{
if (_patrolPoints != null && _patrolPoints.Count >= 2)
{
_currentPatrolIndex = 0;
anim.SetBool("idle", true);
SetDestination();
}
else
{
Debug.Log("Insufficient patrol points.");
}
}
}
public void Update()
{
//Check if we're close to the destination.
if (_travelling && _navMeshAgent.remainingDistance <= 1.0f)
{
_travelling = false;
anim.SetBool("idle", false);
anim.SetBool("move", true);
//If we're going to wait, then wait dumbass!
if (_patrolWaiting)
{
_waiting = true;
_waitTimer = 0f;
anim.SetBool("idle", true);
anim.SetBool("move", false);
}
else
{
ChangePatrolPoint();
SetDestination();
}
}
//Instead if we're waiting...
if (_waiting)
{
_waitTimer += Time.deltaTime;
if (_waitTimer >= _totalWaitingTime)
{
_waiting = false;
anim.SetBool("move", true);
anim.SetBool("idle", false);
ChangePatrolPoint();
SetDestination();
}
}
}
private void SetDestination()
{
if (_patrolPoints != null)
{
Vector3 targetVector = _patrolPoints[_currentPatrolIndex].transform.position;
_navMeshAgent.SetDestination(targetVector);
_travelling = true;
////anim.SetBool("idle", false);
////anim.SetBool("move", true);
}
}
//Selects a new patrol point in the available list, but
//also with a small probability allows for us to move forward or backwards.
private void ChangePatrolPoint()
{
//Unity generate random number between 0 and 1
if (UnityEngine.Random.Range(0f, 1f) <= _switchProbability)
{
//decides if go forward or backwards: whatever the value, make the oposite
_patrolForward = !_patrolForward;
}
if (_patrolForward)
{
//if the patrolpoint exceedes patrolpoints.count, go backs to zero
_currentPatrolIndex = (_currentPatrolIndex + 1) % _patrolPoints.Count;
}
else
{
if (--_currentPatrolIndex < 0)
{
_currentPatrolIndex = _patrolPoints.Count - 1;
}
}
}
}
//Enemy chace player
public class EnemyScript : MonoBehaviour
{
Animator anim;
public float speed = 4;
//follow player
public float enemyDistanceRun = 5.0f; //radius to spot the player
//--
PlayerHealthScript phs;
void Start()
{
anim = GetComponent<Animator>();
}
void Update()
{
if (phs == null)
{
phs = GameObject.Find("Player Character").GetComponent<PlayerHealthScript>();
}
}
public void chasePlayer()
{
if (Vector3.Distance(phs.transform.position, this.transform.position) < 10)
{
Vector3 direction = phs.transform.position - this.transform.position;
direction.y = 0;
this.transform.rotation = Quaternion.Slerp(this.transform.rotation, Quaternion.LookRotation(direction), 0.1f);
if (direction.magnitude > 2)
{
this.transform.Translate(0, 0, 0.05f);
anim.SetBool("chase", true);
anim.SetBool("attack", false);
}
else
{
anim.SetBool("attack", true);
anim.SetBool("chase", false);
anim.SetBool("move", false);
}
}
else
{
anim.SetBool("chase", false);
anim.SetBool("attack", false);
}
}