I am making a AI script. I have already made it so the script checks if the enemy can see the player, based on a raycast that checks if there are any obsticals obscuring the enemy's view of the player.
function CanSeePlayer() : boolean{
var hit : RaycastHit;
var rayDirection = playerObject.transform.position - transform.position;
if (Physics.Raycast (transform.position, rayDirection, hit)) {
if (hit.transform.tag == "Player") {
Debug.Log("Can see player");
return true;
}else{
Debug.Log("Can not see player");
return false;
}
}
}
The problem is that this gives the enemy a 360 degree view, how can i restrict it so the enemy can only see the player if the player is within a 135 degree cone in front of the enemy?
I found a solution to the problem, i used Vector3.Angle to detect how far away from the front of the enemy the player is.
The code ended up looking like this for anyone that might be interested:
function CanSeePlayer() : boolean{
var hit : RaycastHit;
var rayDirection = playerObject.transform.position - transform.position;
if(Physics.Raycast (transform.position, rayDirection, hit)){ // If the player is very close behind the player and in view the enemy will detect the player
if((hit.transform.tag == "Player") && (distanceToPlayer <= minPlayerDetectDistance)){
return true;
}
}
if((Vector3.Angle(rayDirection, transform.forward)) < fieldOfViewRange){ // Detect if player is within the field of view
if (Physics.Raycast (transform.position, rayDirection, hit)) {
if (hit.transform.tag == "Player") {
//Debug.Log("Can see player");
return true;
}else{
//Debug.Log("Can not see player");
return false;
}
}
}
}
Thanks Mattivc!! This helped me a lot... I tried to figure out what some of your variables are since not all of them were declared in your code snippet. Here's my slightly modified version if anyone wants to check out. Just attach this javascript script to the enemy, drag your player to the playerObject variable, and be sure the player is tagged "Player"
var playerObject : GameObject; // the player
var fieldOfViewRange : float; // in degrees (I use 68, this gives the enemy a vision of 136 degrees)
var minPlayerDetectDistance : float; // the distance the player can come behind the enemy without being deteacted
var rayRange : float; // distance the enemy can "see" in front of him
private var rayDirection = Vector3.zero;
function CanSeePlayer() : boolean
{
var hit : RaycastHit;
rayDirection = playerObject.transform.position - transform.position;
var distanceToPlayer = Vector3.Distance(transform.position, playerObject.transform.position);
if(Physics.Raycast (transform.position, rayDirection, hit)){ // If the player is very close behind the enemy and not in view the enemy will detect the player
if((hit.transform.tag == "Player") && (distanceToPlayer <= minPlayerDetectDistance)){
//Debug.Log("Caught player sneaking up behind!");
return true;
}
}
if((Vector3.Angle(rayDirection, transform.forward)) < fieldOfViewRange){ // Detect if player is within the field of view
if (Physics.Raycast (transform.position, rayDirection, hit, rayRange)) {
if (hit.transform.tag == "Player") {
//Debug.Log("Can see player");
return true;
}else{
//Debug.Log("Can not see player");
return false;
}
}
}
}
function OnDrawGizmosSelected ()
{
// Draws a line in front of the player and one behind this is used to visually illustrate the detection ranges in front and behind the enemy
Gizmos.color = Color.magenta; // the color used to detect the player in front
Gizmos.DrawRay (transform.position, transform.forward * rayRange);
Gizmos.color = Color.yellow; // the color used to detect the player from behind
Gizmos.DrawRay (transform.position, transform.forward * -minPlayerDetectDistance);
}
The original question was just about finding the player in front of the enemy, which was exactly what I needed. I took the work of Mattivc and the suggestions of Jfcool10 and vexe and converted it into c# in case anyone else stumbles on this question.
protected bool CanSeePlayer()
{
RaycastHit hit;
Vector3 rayDirection = Player.transform.position - transform.position;
if ((Vector3.Angle(rayDirection, transform.forward)) <= fieldOfViewDegrees * 0.5f)
{
// Detect if player is within the field of view
if (Physics.Raycast(transform.position, rayDirection, out hit, visibilityDistance))
{
return (hit.transform.CompareTag("Player"));
}
}
return false;
}