Hi! I made a FOV that, basically it’s a cone of view (in the Enemy GO) if anyone needs it.
You will need these variables
[Header("General Parameters for FOV")]
public float heightSight = 1.65f; //Look from the eyes
public float heightPlayer = -0.15f; //Height distance from the enemy eyes to the player's neck
[Header("FOV Range")]
public float sightDistance = 8.0f; //Aggro distance
public float patrolFovAngle = 160f; //FOV Angle
float FOVStart; //Auxiliary varible to call the FOV method
float FOVEnd; //Auxiliary varible to call the FOV method
RaycastHit hit; //Check if player is in FOV.
RaycastHit[] hits; //Detect if there are more objects in the way (player is hiding, or something)
[Header("Layer Parameters and TAG")]
public int ignoreLayer = 13; //Ignore Enemy Layer: Enemies can block enemie's FOV
public string playerTag = "Player"; //Auxiliary variable
//Patrol location variables
private Vector3 lastKnownPosition; //Player's last known Position
Start method
private void Start()
{
lastKnownPosition = transform.position; //The enemy will look into his eyes
FOVEnd = (patrolFovAngle/2f); //if FOV Angle is 160°, this is -80°
FOVStart = -FOVEnd; //if FOV Angle is 160°, this is 80°
}
Then, you need to call the following methods: They will return a “true” or “false” if the Player is in the FOV
private bool isInFOV(float FOVangleStart, float FOVangleEnd, GameObject player)
{
Vector3 targetDir = player.transform.position - transform.position; //Get the Vector of Direction of player relative to this gameObject
float angleToPlayer = (Vector3.Angle(targetDir, transform.forward)); //Get the relative vector of player and this gameObject
float inRange = Vector3.Distance(player.transform.position, transform.position); //Get distance between this gameObject and the Player
Vector3 heightSelf = new Vector3(0f, heightSight, 0f); //aux variable to detect height of this gameObject relative to the player
Vector3 heightTarget = new Vector3(0f, heightPlayer, 0f); //aux variable to detect height of this gameObject relative to the player
Ray FOVRay = new Ray(transform.position + heightSelf, targetDir + heightTarget); //Rascating from this gameObject (adjusted) to Player gameObject (adjusted)
Debug.DrawRay(transform.position + heightSelf, (lastKnownPosition - transform.position) + heightTarget, Color.yellow); //Check Last Knwon Position
if (angleToPlayer >= FOVangleStart && angleToPlayer <= FOVangleEnd && (inRange <= sightDistance)) //Check is the Player is angle and distance of the FOV
{
return IgnoreEnemyFOV(targetDir, heightSelf, heightTarget, FOVRay, player); //Ignore enemies MASK
}
else
{
return false;
}
}
private bool IgnoreEnemyFOV(Vector3 targetDir, Vector3 heightSelf, Vector3 heightTarget, Ray FOVRay, GameObject player)
{
int mask = 1 << ignoreLayer; // Ignore all Layers but ignoreLayer
mask = ~mask; //Ignore only ignoreLayer
if (Physics.Raycast(FOVRay, out hit, sightDistance, mask)) //Check if the Player is Blocked | 11: Ignore Enemy Layer
{
if (hit.collider.tag == playerTag) //Check if the impact is actually the player
{
lastKnownPosition = player.transform.position; //LastKnownPosition
Debug.DrawRay(transform.position + heightSelf, targetDir + heightTarget, Color.green); //Where is the player
return true;
}
else
{
Debug.DrawRay(transform.position + heightSelf, targetDir + heightTarget, Color.red); //The player is beyond an obstacle
return false;
}
}
else
{
return false;
}
}
At the end you will see a Yellow Ray to the last know position, a Green to the actual position, and a Red if the player is hiding.
Just remember to change your Enemies to the Enemy Layer (in my case is 13), name your player tag to “Player”, and I think that is all.
PS: Remember to remove the Debug.DrawRay.