Hello. I would like to make a raycast system for my enemy for when he sees the player to shoot, but when he doesn’t see the shooter to stop shooting and continue on his navigation mesh path. Right now I have it to where he is using a box collider to see if the player is “in range” but since that goes through walls it isn’t the optimal thing to do. Please help if you can! Also with C# please!
This is broadly called “line of sight” or LOS… google up unity tutorial line of sight and there’s a bunch of interesting stuff. Some is 2D, some is 3D so pay attention to what the tutorial’s assumptions are.
A basic approach is to shoot Raycasts (Unity - Scripting API: Physics.Raycast) from the enemy AI in direction to the player. Here the player will be recognized if the distance is matching and if no obstacle (like a wall) is blocking the sight. Another technique is to raycast in the direction the AI is looking. In the last setup the AI recognizes the player much later because the player can hide himself in the blind spot.
Thank you!!
Thank you for the help!
Here’s some code for a view-dependent AI. Simply define a viewAngle for the AI like 90 degree.
bool findThePlayer()
{
if (Vector3.Distance(transform.position, playerPos.position) < viewDistance)
{
Vector3 directionToPlayer = (playerPos.position - transform.position).normalized;
float angleBetweenGuardAndPlayer = Vector3.Angle(transform.forward, directionToPlayer);
if (angleBetweenGuardAndPlayer < viewAngle / 2)
{
Debug.Log("viewAngle " + viewAngle);
if (!Physics.Linecast(transform.position, playerPos.position))
{
return true;
}
}
}
return false;
}
Thank you so much! The example on the Unity page shows ten units forward (But I still wasn’t sure how to incorporate that with player’s position so thank you so much again)… could I limit the view to only going so far with the angle or is it already doing that?
It limits the view angle and the view distance of the npc (and the npc cant look through walls etc.):
float viewDistance = 10f;
float viewAngle = 90f;
// Here you have to pass the players position by the players transform
bool findThePlayer(Transform playerPos)
{
if (Vector3.Distance(transform.position, playerPos.position) < viewDistance)
{
Vector3 directionToPlayer = (playerPos.position - transform.position).normalized;
float angleBetweenGuardAndPlayer = Vector3.Angle(transform.forward, directionToPlayer);
if (angleBetweenGuardAndPlayer < viewAngle / 2)
{
Debug.Log("viewAngle " + viewAngle);
if (!Physics.Linecast(transform.position, playerPos.position))
{
return true;
}
}
}
return false;
}
Thank you so much!!!