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
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.
It actually requires the CFrame of the currentcamera, but its pretty inacurate.