How can I detect if a part is not being rendered?

I made a script that takes a position of a part then converts it to a screen point, then print out the results. But it still prints the screen point even if the part is not rendered on the screen. How can I detect if the part is not being rendered (For example: someone turned their camera around so they could not see the part)?

Here is the script:

local Camera = workspace:WaitForChild("Camera")

game:GetService("RunService").Heartbeat:Connect(function(dt)
	local vec = Camera:WorldToScreenPoint(workspace.Part.Position)
	print(vec.X)
end)

EDIT: Forgot to mention that the script is just a localscript

The 2nd return argument in :WorldToScreenPoint is a bool which states if the part is currently in front of the camera. (AKA being rendered)

Try changing local vec to…

local vec, IsRendered = blablabla

5 Likes

Since the vector point on the screen is always the first return value and the “is on screen” boolean is always the second value, you can do this:

local Camera = workspace:WaitForChild("Camera")

game:GetService("RunService").Heartbeat:Connect(function(dt)
	local _, isOnScreen = Camera:WorldToScreenPoint(workspace.Part.Position)
    print(isOnScreen)
end)
5 Likes

When calling the WorldToScreenPoint function with Part.Position only, using the second return value is not sufficient to know whether or not the part can be seen. This only tells you if the center of the part’s bounding box is within the bounds of your screen, allowing for half the part to still be visible and rendered on screen.

You could call this function in a loop to check all 8 corners of the Part’s bounding box (exiting the loop early if any corner returns true) to know if the whole object is definitely not within screen bounds (not the same thing as either can-be-seen or is-rendered, as explained below).

If whether or not the part is being rendered is your concern, you need to check other things like Part.Transparency and if the part has any non-transparent Decals or Textures on it that would cause it to be rendered. A fully Transparency=1 part with no Decals, Textures, SurfaceGui, etc. adorning it is not rendered.

If what you really care about is whether or not the camera (user) actually can see the part–not occluded–that’s the hardest problem of all. In fact, you can’t really get a 100% accurate result with raycasts. Even if you were to do the impractical 1 ray per screen pixel, there are ways to make parts transparent with decals that rays can’t detect, and rays also hit the collision geometry of mesh and CSG parts, which may not occlude the part even if the visual geometry does (or vice versa). Code for things like “can my NPC baddie see Player X” is always approximated with a small number of rays in practice.

1 Like