I’m making a horror game and a feature I’m trying to make is a way to tell if a player is not looking or looking at a part. This would have to take into account things like walls that could obstruct the player’s view of the part. What is the best way to do this?
The best way would be to use “:WorldToScreenPoint()” inside of an event loop which fires every frame, specifically “.RenderStepped”. Here’s a fairly simple script I wrote which works.
https://developer.roblox.com/en-us/api-reference/function/Camera/WorldToScreenPoint
local run = game:GetService("RunService")
local camera = workspace.CurrentCamera
local part = workspace:WaitForChild("Part")
local function onRenderedFrame()
local position, visible = camera:WorldToScreenPoint(part.Position)
if visible then
print("Part is visible!")
end
end
run.RenderStepped:Connect(onRenderedFrame)
Wait does this take into account walls?
No, but you could use raycasting to check that. Here’s an article on it in case you don’t already know: Intro to Raycasting
So every tick of that stepped sends a single ray to the center of the position I want to be checked for looking???
Pretty much. You’d probably narrow it down first. Maybe something like this:
- All your parts the player can look at >
- of those parts, all the parts within a distance of the player >
- of those parts, all the parts on screen >
- of those parts, all the parts that pass the raycast check
(Note that raycasting only checks if the center of the part is on the screen.)
Unfortunately yes, so I recommend finding a way to run your script without checking every tick and only checking when the information is needed. If you can’t do that though, you should not run the raycast check whenever the object isn’t on your screen to lower the possible lag as much as possible.
Ok heres what I got so far: This is script inside a part inside workspace. I cant seem to get the visible part to work. Am I not difining camera correctly?
local sP = script.Parent
local camera = workspace.CurrentCamera
local checkForVisablility = true
local function checkForPartVisablity()
print(“Checking for part visibility”)
–Creates a loop that runs once every physics tick
local stepped
stepped = game:GetService(“RunService”).Stepped:Connect(function()
if checkForVisablility then
local position, visible = camera:WorldToScreenPoint(sP.Position)
if visible then
print(“Part is visible!”)
else
print(“Part is not visible!”)
end
else
print(“No longer checking for part visibility”)
stepped:Disconnect()
end
end)
end
checkForPartVisablity()
You have to use a LocalScript for it to work, because the camera is only in that position for that player’s client. The server’s camera stays in the default position.
Also, by default the camera’s name is “Camera” not “CurrentCamera”. Unless you changed the camera’s name, you should change that to local camera = workspace.Camera
Try making those changes and see if it works then.
The local script does not run when I put the code and made the changes you said into it.
Did you make sure to put the local script in StarterPlayerScripts? You may have to change a lot of the script for it to work without being in the part, but it is necessary for the script to run. Unfortunately local scripts don’t run when in workspace.
I need a direction for the ray Im sending out. Can I do something like Cframe.new(torsoposition, part) * visibleDistance?
I’m not too familiar with raycasting so I won’t be any help beyond this, but when creating a raycast you have the origin and direction. The origin is the camera’s position (workspace.Camera.CFrame.Position
). The direction is the part’s position relative to the camera’s position. In my head this should be the camera’s position minus the part’s position, but again I’m not familiar with raycasting. Sorry that I can’t help you anymore
Here this is what Im trying to do. Direction is not what it wants Idk why, but I have an example of a direction from a projectile raycast working.
local direction = part.Position + CFrame.new(part.Position, workspace.Camera.CFrame.Position) * 100 | ||||
---|---|---|---|---|
local result = workspace:Raycast(workspace.Camera.CFrame.Position, direction) |
|||local currentNormal = partCFrame.LookVector|
|||local direction = currentNormal * 1|
im really sorry to bump such an old post, but this is the second result on google and i’d hate for people to see this unsolved. So here’s a simple script that allows you to check if the player can see the part. This also takes account walls:
local origin = camera.CFrame.Position
local direction = (target_part.Position - origin).Unit
local result = workspace:Raycast(origin, direction * 15000)
if result and result.Instance == target_part then
print('plr can see part ')
end
@Its4Realzies if you have any questions feel free to ask
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.