You can do this without raycasting, but it won’t be able to check for obstructions.
The way to do this is by simply measuring the angle between both objects. This can be done by taking the arc-cosine from the dot product of two normal vectors (i.e. look vectors). In your use-case, you would use the part’s direction, then find the direction to the point you’re checking by simply subtracting the two positions and using that unit vector (i.e. normal vector).
A function to check the angle might look like this:
local function AngleBetween(vectorA, vectorB)
return math.acos(math.clamp(vectorA:Dot(vectorB), -1, 1))
end
It’s important to note again that the above function expects unit vectors. A unit vector is simply a vector whose magnitude is 1. The .Unit
property of a vector will return this.
Ok, so to see if your point is within a certain field of view from a part, you first need to grab the correct vectors to check. In this code, I will use part
to represent the gray block where the FOV is coming from, and will use point
to represent the part that is being checked.
Let’s get our vectors:
-- Imagine this as a line coming straight through the center of your FOV sweep:
local lookForward = part.CFrame.LookVector
-- Imagine this as a line going directly to the point we're checking:
local lookToPoint = (point.Position - part.Position).Unit
Now that we have our two look vectors, we can measure the angle between them. We simply feed them into our AngleBetween
function:
local angle = AngleBetween(lookForward, lookToPoint)
Now we have our angle (in radians). We can now check if it’s within our FOV range. But we need to be careful! The angle will be a measurement from the center. Therefore, we need to measure the absolute angle (simply use math.abs
) and then check based on half of our defined FOV range.
So if our FOV range is defined as 70°, then we need to check if the absolute angle measured is within half of 70°, so we would simply check if it’s less or equal to 35°.
local FOV = math.rad(70)
-- All the other code we wrote goes here
if math.abs(angle) <= FOV / 2 then
print("Within range!")
else
print("Not within range")
end
Ok, so altogether now!
-- Field of view (in degrees):
local FOV = 70
-- Define stuff:
local part = workspace.Part
local point = workspace.Point
local fovCheck = math.rad(FOV) / 2
-- Find angle between two normalized vectors:
local function AngleBetween(vectorA, vectorB)
return math.acos(math.clamp(vectorA:Dot(vectorB), -1, 1))
end
-- Get the two lookvectors:
local lookForward = part.CFrame.LookVector
local lookToPoint = (point.Position - part.Position).Unit
-- Calculate angle between our two lookvectors:
local angle = AngleBetween(lookForward, lookToPoint)
-- Check if the angle is within range:
if math.abs(angle) <= fovCheck then
print("Within range!")
else
print("Not within range")
end
Final note: This is basing the origin and direction of the FOV from the lookvector of that gray part. In your image, most likely you’re casting from the right or left. If you want to continue doing that, you can change the definition of lookForward
to use the RightVector
. You can simply negate it for the left vector.