I want to detect when a player sees an object in their field of view if it isn’t obstructed by an obstruction.
I have made this script:
local enemy = game.Workspace.testenemy
local char = game.Players.LocalPlayer.Character
local function detect(enemyname)
local rayOrigion = char.Head.Position
local rayDirection = char.Head.Orientation
local raycastFilter = RaycastParams.new()
raycastFilter.FilterType = Enum.RaycastFilterType.Exclude
raycastFilter.FilterDescendantsInstances = {char}
local raycastResult = workspace:Raycast(rayOrigion, rayDirection * 1000, raycastFilter)
local raycast = game.Workspace:Raycast(rayOrigion,rayDirection)
print(raycastResult)
if raycastResult then
if raycastResult.Instance.Parent.Name == enemyname then
return raycastResult.Instance.Parent.Name
else
return
end
end
end
while true do
task.wait(0.2) --for the sake of playtesting ive made this 0.2 instead of empty
local isVisible = detect(enemy.Name)
print(isVisible)
if isVisible == enemy.Name then
print("visible")
else
print("notvisible")
end
end
However this is a script for if a player is looking directly at an object, and it doesn’t even work correctly.
(example: looking directly at enemy does not detect it, however jumping on top of it and looking down works)
I have tried alot of things but none of them ended up being more not broken.
Does “field of view” refer to the character’s head or the camera? If you’re locking first-person these may mean the same thing.
You could use the method Camera:WorldToViewportPoint() do determine whether a point is in the field of view of the camera. If so, then construct a ray from the viewport position towards the target and raycast to check for collisions.
hello, i understand this but i am confused on how to construct a ray from the viewport position to the target.
local camera = workspace.CurrentCamera
local vector, inViewport = camera:WorldToViewportPoint(enemy.Head.Position)
local onScreen = inViewport and vector.Z > 0
if onScreen then
local viewpointtoray = camera:ViewportPointToRay(vector.X,vector.Y * 500)
print(viewpointtoray, onScreen)
if viewpointtoray then
return "yeah"
end
i’ve done this and it returns yes even if theres a wall
sorry if this is really obvious, i dont know how to work with cameras well :<
Here you go. This script uses the corners of the object to check if you can see it, by using raycasts
local function getAllCornersFromOrientationAndSize(orientation, size)
local corners = {}
for x = -0.5, 0.5, 1 do
for y = -0.5, 0.5, 1 do
for z = -0.5, 0.5, 1 do
table.insert(corners, orientation.Position + orientation:VectorToWorldSpace(Vector3.new(x * size.X, y * size.Y, z * size.Z)))
end
end
end
return corners
end
local function getOrientationAndSize(obj)
local orientation, size
if obj:IsA("Model") then
orientation, size = obj:GetBoundingBox()
else
orientation, size = obj:GetPivot(), obj.Size
end
return orientation, size
end
local camera = workspace.CurrentCamera
function IsObjectObscured(obj)
local orientation, size = getOrientationAndSize(obj)
local corners = getAllCornersFromOrientationAndSize(orientation, size)
local cameraPosition = camera.CFrame.Position
for _, corner in ipairs(corners) do
local rayDirection = (corner - cameraPosition).Unit
local params = RaycastParams.new()
params.FilterDescendantsInstances = {obj}
params.FilterType = Enum.RaycastFilterType.Exclude
local raycastResult = workspace:Raycast(cameraPosition, rayDirection * (corner - cameraPosition).Magnitude, params)
if not raycastResult then
return false -- At least one corner is unobscured
end
end
return true -- All corners are obscured
end
local isObscured = IsObjectObscured(workspace.Part)
if isObscured then
print("Object is fully obscured")
else
print("Object has at least one visible corner")
end