Check if part is on screen? (Not Position)

Hello devs! So I’ve been thinking about this problem that I’ve got for a while now, so, how would I go about checking if Part is on screen not a Position.

Note : Yes I know about ViewportToWorldPoint but that takes Position, not Part.

Perform a raycast operation from the camera’s position to the part, if the view is obstructed the ray will intersect with a different part/terrain cell.

local Game = game
local Workspace = workspace
local Camera = Workspace.CurrentCamera
local Players = Game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Part = Workspace:WaitForChild("Part") --Part to check.

local Parameters = RaycastParams.new()
Parameters.FilterDescendantsInstances = {Character}

while true do
	task.wait(1) --Yield for one second between each cycle.
	local Origin = Camera.CFrame.Position
	local Direction = (Part.Position - Origin).Unit
	local Result = Workspace:Raycast(Origin, Direction * 250, Parameters)
	if Result then
		--Query the result of the raycast operation.
	end
end
1 Like

But uhh it doesn’t check if the part is on screen, it checks if there’s something intersecting camera and part.

Result.Instance will be a reference to the part if it is on the screen.

you would need to use WorldToViewportPoint on all 8 corners of the part

so you would use the WorldToViewportPoint on each red dot and if just 1 of the red dots are in view then you know the part is in view

you can find more information on the old documentation
https://developer.roblox.com/en-us/api-reference/function/Camera/WorldToViewportPoint

local function InView(part)
	local edges = {
		part.CFrame * Vector3.new(-part.Size.X / 2, part.Size.Y / 2, -part.Size.Z / 2)
		part.CFrame * Vector3.new(part.Size.X / 2, part.Size.Y / 2, -part.Size.Z / 2)
		part.CFrame * Vector3.new(-part.Size.X / 2, part.Size.Y / 2, part.Size.Z / 2)
		part.CFrame * Vector3.new(part.Size.X / 2, part.Size.Y / 2, part.Size.Z / 2)
		part.CFrame * Vector3.new(-part.Size.X / 2, -part.Size.Y / 2, -part.Size.Z / 2)
		part.CFrame * Vector3.new(part.Size.X / 2, -part.Size.Y / 2, -part.Size.Z / 2)
		part.CFrame * Vector3.new(-part.Size.X / 2, -part.Size.Y / 2, part.Size.Z / 2)
		part.CFrame * Vector3.new(part.Size.X / 2, -part.Size.Y / 2, part.Size.Z / 2)
	}
	for i, edge in edges do
		local viewPoint, inView = camera:WorldToViewportPoint(edge)
		if inView == true then return true end
	end
	return false
end
2 Likes

it checks if there’s something intersecting camera and part.

It performs a raycast operation from the camera’s position to the part, if the part is unobstructed, ‘Result.Instance’ will refer to it, if the part is obstructed, ‘Result.Instance’ will refer to the part that obstructed it.