- Home /
Enemy AI, detect player when seen
Hey guys,
O.k so I am working on a project for college but I am a total Noob when it comes to Unity and scripting, to be honest I have no idea why we are making a game so early but there you go! Anyway, I have just about everything working but I need help with enemy AI. It's a stealth game so I am really looking for a simple script that allows the enemy to patrol and attack is he spots the player. I found this script and it sounds exactly like what I need but I cannot get it to work. Also, the rest of the game is in c# and i think this is a unityscript. It says to attach it to place it in the update function but when I try to run it I get "Unknown identifier : 'maxDistance'. and "Unknown identifier : 'playerObject'. errors. I'm sure it's an easy fix but I just don't know how to, any help would be HUGELY appreciated because the project is due tomorrow!
Here's the script
//if an enemy as further than maxDistance from you, it cannot see you
var maxDistanceSquared = maxDistance * maxDistance;
var rayDirection : Vector3 = playerObject.transform.localPosition - transform.localPosition;
var enemyDirection : Vector3 = transform.TransformDirection(Vector3.forward);
var angleDot = Vector3.Dot(rayDirection, enemyDirection);
var playerInFrontOfEnemy = angleDot > 0.0;
var playerCloseToEnemy = rayDirection.sqrMagnitude < maxDistanceSquared;
if ( playerInFrontOfEnemy && playerCloseToEnemy)
{
//by using a Raycast you make sure an enemy does not see you
//if there is a bulduing separating you from his view, for example
//the enemy only sees you if it has you in open view
var hit : RaycastHit;
if (Physics.Raycast (transform.position,rayDirection, hit, maxDistance)
&& hit.collider.gameObject==playerObject) //player object here will be your Player GameObject
{
//enemy sees you - perform some action
}
else
{
//enemy doesn't see you
}
}
Answer by cdrandin · Apr 14, 2013 at 07:10 PM
Once you got that, now work on the AI notice the player when within a certain distance. SO, take the different of the AI and the player, if it is less than AI_Notice_Distance
then have the AI acknowledge the player's existence. SO, you can have it rotate to the player or something. GameObject.Find(...), transform.position.distance(player.position,AI.position)
From there you can then make it slight more complex by obscuring the AI's view, so if there is a wall between the player and the AI, then the AI will not acknowledge the player. TO do this you can cast a Ray from the AI to the player and see if anything is obscuring. If you want more accuracy then you will use more Raycast along the vertical axis, in case of short wall or some other objects. Check out Raycast and HitCast in the manual.
From there you can then do soo many more things to improve AI. AI is amongst the hardest task to mimic that of human interaction and is very in depth field. Check out some free reads online about AI and what more could you do.
Hey!I managed to get the enemy to follow my player but I want him to only do it when he "sees" him. If the player is hidden he shouldn't be spottable. Just wondering if you know how I would add a field of view to him?
Here's the code
using UnityEngine; using System.Collections;
public class EnemyAi : $$anonymous$$onoBehaviour { public Transform target; public int moveSpeed; public int rotationSpeed; public int maxdistance;
private Transform myTransform;
void Awake(){
myTransform = transform;
}
void Start () {
GameObject go = GameObject.FindGameObjectWithTag("Player");
target = go.transform;
maxdistance = 2;
}
void Update () {
Debug.DrawLine(target.position, myTransform.position, Color.red);
myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed * Time.deltaTime);
if(Vector3.Distance(target.position, myTransform.position) > maxdistance){
//$$anonymous$$ove towards target
myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
}
}
}
Like I said previously, cast some Raycast towards the player object starting from the current AI. If there is nothing, lets say tag="WALL" in the way then FoV is open so the AI can see the player. You should have multiple raycast or depending on your game have on in a good spot so you don't happen to miss this "WALL" when checking for FoV block.
Answer by jeremysmartcs · Dec 09, 2017 at 08:10 AM
Here's a low tech but effective solution which incorporates Raycast with Commandos style 'scanning' - not visible to player but covers a cone of vision of the enemy. This code also draws a line in debug to show how the Raycast is behaving. If player is hidden behind a collider, enemy Raycast is blocked and enemy doesn't see the player - Player GameObject needs to have a tag assigned "Player".
Don't forget to declare LeftRightZ bool. 'MEyes' is a child object of the enemy where their eyes are. Feel free to play with the numbers or replace with variables but this one works for my game.
if(LeftRightZ)
{
if(EyeScanZ < 30)
{
EyeScanZ += 100 * Time.deltaTime;
}
else
{
LeftRightZ = false;
}
}
else
{
if (EyeScanZ > -30)
{
EyeScanZ -= 100 * Time.deltaTime;
}
else
{
LeftRightZ = true;
}
}
transform.Find("MEyes").transform.localEulerAngles = new Vector3(0, EyeScanZ);
RaycastHit hit;
Debug.DrawRay(transform.Find("MEyes").position, transform.Find("MEyes").transform.forward * ViewDistance);
if (Physics.Raycast(transform.Find("MEyes").position, transform.Find("MEyes").transform.forward * ViewDistance, out hit, ViewDistance))
{
if(hit.transform.gameObject.tag == "Player")
{
Debug.Log(gameObject.name + " CAN see Player");
}
}
,Here's a low tech but effective solution which incorporates Raycast with Commandos style 'scanning' - not visible to player but covers a cone of vision of the enemy. This code also draws a line in debug to show how the Raycast is behaving. If player is hidden behind a collider, enemy Raycast is blocked and enemy doesn't see the player - Player GameObject needs to have a tag assigned "Player".
Don't forget to declare LeftRightZ bool. 'MEyes' is a child object of the enemy where their eyes are. Feel free to play with the numbers or replace with variables but this one works for my game.
if(LeftRightZ)
{
if(EyeScanZ < 30)
{
EyeScanZ += 100 * Time.deltaTime;
}
else
{
LeftRightZ = false;
}
}
else
{
if (EyeScanZ > -30)
{
EyeScanZ -= 100 * Time.deltaTime;
}
else
{
LeftRightZ = true;
}
}
transform.Find("MEyes").transform.localEulerAngles = new Vector3(0, EyeScanZ);
RaycastHit hit;
Debug.DrawRay(transform.Find("MEyes").position, transform.Find("MEyes").transform.forward * ViewDistance);
if (Physics.Raycast(transform.Find("MEyes").position, transform.Find("MEyes").transform.forward * ViewDistance, out hit, ViewDistance))
{
if(hit.transform.gameObject.tag == "Player")
{
Debug.Log(gameObject.name + " CAN see Player");
}
}
Your answer
Follow this Question
Related Questions
raycast hit not detecting && Nav mesh agent ai stealth 1 Answer
AI detection script problem 0 Answers
Enemy Ai Field of View 0 Answers
enemy raycast to detect player 1 Answer
180 Degree raycast 1 Answer