Finding enemies within a angle and distance

Hello! Currently I am working on an boss fight and im wondering how would you find enemies within a angle/triangle something like this
Ex: Orange is boss, Blue is angle, Pink is enemies, x’s are for not included in the count (not in angle)
I want it to find every enemy within the angle and distance but not the enemies not inside the angle, something like vision

1 Like

Could dot products be a possible solution here? You could incorporate a distance check as well to determine if players are close enough in some given angle.

local function isPlayerInLineOfSight(player)
local lookDirection = rootPart.CFrame.LookVector
local directionToPlayer = (player.PrimaryPart.Position - rootPart.Position).Unit

local angle = lookDirection:Dot(directionToPlayer)

if angle < 1 then
--//Player is in line of sight

Could also adjust the maximum angle it can be, I believe anything less than 1 is in front of the NPC, and anything negative is behind it. You should be able to tighten this, and also incorporate a distance check to see if players in line of sight are also close enough.


Another thing to consider is what you want the 3D shape of the “angle” to be. Do you want “full 3D” angle, i.e. a cone shape, or do you want more of a 2D, top-down type angle, i.e. ignoring the height component for a “two planes” type of shape?

For the cone-type shape, this should work:

function vectorAngle(v1: Vector3, v2: Vector3): number
    --Explanation here:
    return math.acos(v1.Unit:Dot(v2.Unit))

function isPointInCone(point: Vector3, coneBase: Vector3, coneDir: Vector3, coneAngle: number): boolean
    local baseToPoint = point - coneBase
    local angle = vectorAngle(baseToPoint, coneDir)
    return angle < coneAngle

function isPointInRange(point: Vector3, pointFrom: Vector3, maxRange: number, minRange: number?): boolean
    local d = (point - pointFrom).Magnitude
    return d  == math.clamp(d, minRange or 0, maxRange)

  function isPointInView(point: Vector3, view: Attachment, viewAngle: number, viewRange: number): boolean
      return isPointInCone(point, view.WorldPosition, view.WorldCFrame.LookVector, viewAngle) and
           isPointInRange(point, view.WorldPosition, viewRange) 

For a two-planes-type shape you could just remove the Y component:

function isPointInBiPlaneFrustrum(
    point: Vector3, plane1Point: Vector3, plane1Normal: Vector3, 
    plane2Point: Vector3, plane2Normal: Vector3): boolean --I swear this function name makes sense SOMEHOW
    local pointToPlane1Point = plane1Point - point
    local pointToPlane2Point = plane2Point - point
    local rightSideOfPlane1 = pointToPlane1Point:Dot(plane1Normal) > 0
    local rightSideOfPlane2 = pointToPlane2Point:Dot(plane2Normal) > 0
    return rightSideOfPlane1 and rightSideOfPlane2

function isPointInView(point: Vector3, view: Attachment, viewAngle: number, viewRange: number)
	local planeNormal1 = (view.WorldCFrame * CFrame.Angles(0, -viewAngle/2, 0)).LookVector
	local planeNormal2 = (view.WorldCFrame * CFrame.Angles(0,  viewAngle/2, 0)).LookVector
	A.CFrame =, view.WorldPosition + planeNormal1) *, 0, 0)
	B.CFrame =, view.WorldPosition + planeNormal2) *, 0, 0)
	return isPointInBiPlaneFrustrum(point, view.WorldPosition, planeNormal1, view.WorldPosition, planeNormal2) 
		and isPointInRange(point, view.WorldPosition, viewRange) 

Here’s an illustration of what the view shape looks like, defined by a “Boss” part:


Hey its been a while since you sent this, im a bit confused on what to insert into the functions, for the cone shape without the y component, these are functions so where would i get the a,b in isPointInView, and how would I really use these in a function to check?

Whoops, looks like those were just some debugging things I forgot to remove. You should be able to just remove those two lines beginning with A.CFrame and B.CFrame.

You can use the functions to check if a specific point is inside the shape that each function represents. So if you have a list of all enemies, you can get a list of all enemies in view by looping through all enemies, checking if each one is in view, and inserting them into another table if they are.

Could you show me a way I could maybe use this idk how to use the functions well