How to check if something is in a player's FoV?

Hello, I’m currently making an SCP game, and need to make SCP-173 (If you look away, 173 snaps your neck). Anyway, I need to know how I can make a script check if an object is in a player’s field of view, how can I do this?

Perhaps this will help you

This function can help you: https://developer.roblox.com/en-us/api-reference/function/Camera/WorldToViewportPoint

The function above returns two values, a Vector3 that represents the offset of the world point from the top-left corner of the screen, and a bool that indicates whether or not the point can be seen on the screen. It will be true if it’s on-screen, otherwise it’s false

5 Likes

Part’s have CFrames, CFrames have a property called LookVector, which is a unit vector in the direction the part is facing.

From trigonometry, A:Dot(B) / (len(A)len(B)) is the cosine of the angle between A and B:

and a unit vector is a vector with a magnitude of 1, so dividing by the magnitude of a unit vector makes no difference, aka is trivial.

Therefore the angle between two vectors in RBXLua is:

local a = Vector3.new(1,5,3)
local b = Vector3.new(2,-1,0)
local angleBetween = math.acos(a.unit:Dot(b.unit))

This gives the angle in radians, and a players fov is by default 70 degrees, pi/2 radians is 90 degrees, so if we do 7/9 * pi/2 to get 70 degrees in radians, we can then do an if check

if angleBetween > math.pi/2 * 7/9 then
    --PLAYER IS LOOKING AWAY!
end

and the code can be made into a function passing in a,b as arguments and returning true/false for looking away status:

function IsPlayerLookingAt(PlayerHead, Model)
    local a = PlayerHead.CFrame.LookVector
    local b = Model.PrimaryPart.CFrame.LookVector

    local angleBetween = math.acos(a.unit:Dot(b.unit))
    return angleBetween < math.pi*7/18
end

And then solving whether the player can see the monster is just using IsPlayerLookingAt and a Raycast to check for obstructions.

4 Likes

It actually requires the CFrame of the currentcamera, but its pretty inacurate.