How to evade Enemy AI?
So I have my enemy AI (police car) made of three main scripts, the pursuit, patrol and field of view. At the moment I have it so that when the player enters the line of sight and view range the police car enters pursuit. My problem is I'm not sure how to make it so that the player can evade the police AI. I was planning on using something like if dstToTarget > 150? along with setting it up so that if the target is no longer visible wait 30 seconds before abandoning but have no idea how to go about it. Any help would be awesome, thanks in advance!
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class FieldOfView : MonoBehaviour
{
NavMeshAgent agent;
public bool inPursuit = false;
public bool test = false;
public Transform target;
public Transform self;
public Patrol scriptPatrol;
public Follow scriptPursuit;
public NavMeshAgent scriptNavAgent;
public bool InPursuit = false;
public bool InPatrol = true;
public float viewRadius;
[Range(0, 360)]
public float viewAngle;
public LayerMask targetMask;
public LayerMask obstacleMask;
public GameObject PoliceLights;
public GameObject PoliceSiren;
[HideInInspector]
public List<Transform> visibleTargets = new List<Transform>();
void Start()
{
scriptPursuit = GetComponent<Follow>();
scriptPatrol = GetComponent<Patrol>();
scriptNavAgent = GetComponent<NavMeshAgent>();
InPatrol = true;
InPursuit = false;
StartCoroutine("FindTargetsWithDelay", .2f);
}
IEnumerator FindTargetsWithDelay(float delay)
{
while (true)
{
yield return new WaitForSeconds(delay);
FindVisibleTargets();
}
}
void FindVisibleTargets()
{
visibleTargets.Clear();
Collider[] targetsInViewRadius = Physics.OverlapSphere(transform.position, viewRadius, targetMask);
for (int i = 0; i < targetsInViewRadius.Length; i++)
{
Transform target = targetsInViewRadius[i].transform;
Vector3 dirToTarget = (target.position - transform.position).normalized;
if (Vector3.Angle(transform.forward, dirToTarget) < viewAngle / 2)
{
float dstToTarget = Vector3.Distance(transform.position, target.position);
if (!Physics.Raycast(transform.position, dirToTarget, dstToTarget, obstacleMask))
{
visibleTargets.Add(target);
print("I am in pursuit of the suspect!");
scriptNavAgent.enabled = true;
scriptPatrol.enabled = false;
scriptPursuit.enabled = true;
InPatrol = false;
InPursuit = true;
PoliceLights.SetActive(true);
PoliceSiren.SetActive(true);
inPursuit = true;
}
if (dstToTarget < 20)
{
agent.speed = 5;
}
if (dstToTarget < 5)
{
agent.speed = 1;
}
if (dstToTarget < 1)
{
agent.speed = 0;
}
}
}
}
public Vector3 DirFromAngle(float angleInDegrees, bool angleIsGlobal)
{
if (!angleIsGlobal)
{
angleInDegrees += transform.eulerAngles.y;
}
return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), 0, Mathf.Cos(angleInDegrees * Mathf.Deg2Rad));
}
}
Answer by rmassanet · Jul 19, 2016 at 11:46 AM
That depends a lot on what your desired outcome is. You proposed a valid solution to the problem, which is taking player distance into account.
You can also consider obstacles blocking the AI's line of sight, by tracing a ray from the AI to the player and check if it intersects any blocking object. That would be a very quick and dirty way of doing it.
You could also implement "hiding" spots so that when the player walks into a trigger marked as "hide", while being out of sight of the AI, then the AI won't recover line of sight with the player.
But, of course, first of all, you need the define the expected behaviour, and then get to code it :-)
Oh thank you for the hiding spots idea I really like that. Well I want to use both when the player is no longer in sight (and I have set up buildings to block the line of vision) and use the distance also so that even if they are in sight if they are more than 200 units away it wont pursue. $$anonymous$$y problem is that I don't know how to do this. I don't know which part of my script I need to put the evade parameters. I tried putting in an else if statement underneath and all sorts of things. Basically I understand how to write the function that will make it evade but I dont know how or where to trigger it. Thanks for your response!
So, you need to somehow clear the pursuit of targets that were in sight before and are no longer in sight?
I would keep a reference to the current target. After you compute the targets that are in sight, you need to check whether or not the current target is still in sight or not. If it is not, you need to properly change the AI's status. So, if the current target is not in sight anymore, but there are others in sight, change current target. If there are no targets in sight, just go back to patrolling.
Does that make sense?
Yeah that makes sense thanks. I did at one point have something working though simply using an if statement below the first statement that triggers the pursuit but it wasn't perfect and I made some changes and lost it. The if statement that starts the pursuit in the above script is checking all the time though I think? I would have thought using a simple else statement would have worked to end the pursuit.
Your answer
Follow this Question
Related Questions
How to highlight area that is NOT in the field of view rage of a GUN/CCTV Camera 0 Answers
Navmesh agent enemy moving to players last seen position 0 Answers
Enemy follow player 0 Answers
Camera Field of View 2 Answers
Enemy AI chase, then attack player 1 Answer