Get everything the camera can see?

I’ve had a remaining issue of not being able to get everything the player/camera can see.

I’ve tried using region3 but I don’t get it right and I just get everything BEHIND the camera somehow. I
don’t want to check if there’s parts obscuring every descendant of workspace, as that’s laggy. It’s all been trial and error.

Does anyone have a solution to this issue?

You can turn the camera into 4 planes since its just a pyramid shape. Then you can do checks to see if a part is on the inside of all 4 planes. If it is, it’s in the camera volume.

However there are like 3 gotchas that will make this turn into a ton of work. So what is it you are using this for? You can probably use somehing easier to get the same effect.

Have you ever tried using Dot Product from the camera with the field of view as the max size?

This maybe works?

function GetVisibleParts(Distance : number, OverlapParam: OverlapParams?)
	OverlapParam = OverlapParam or OverlapParams.new()
	Distance = math.min(Distance, 2048)
	
	local Camera = workspace.CurrentCamera
	
	local BaseWedge = Instance.new("CornerWedgePart")
	BaseWedge.Anchored = true
	BaseWedge.CanCollide = false
	BaseWedge.Transparency = 1

	local Size = Vector3.new(math.tan(math.rad(Camera.MaxAxisFieldOfView / 2)), 1, math.tan(math.rad(Camera.FieldOfView / 2))) * Distance
	local Offset = Vector3.new(Size.X / 2, Size.Z / 2, -Distance / 2)
	
	local PartPlacements = {
		{-1, -1, false},
		{1, -1, true},
		{1, 1, false},
		{-1, 1, true}
	}
	
	local Parts = {}
	for Index,Config in ipairs(PartPlacements) do
		local Wedge = BaseWedge:Clone()
		Wedge.Parent = workspace
		Wedge.CFrame = Camera.CFrame * CFrame.new(Offset.X * Config[1], Offset.Y * Config[2], Offset.Z) * CFrame.Angles(math.rad(90), math.rad((Index - 1) * 90), 0)
		Wedge.Size = Config[3] and Vector3.new(Size.Z, Size.Y, Size.X) or Size
		
		for _,Part in ipairs(workspace:GetPartsInPart(Wedge, OverlapParam)) do
			if not table.find(Parts, Part) then table.insert(Parts, Part) end
		end
		Wedge:Destroy()
	end
	
	return Parts
end

It’s a bit overly complicated, but it is able to quite precisely get which parts are and aren’t on screen. However, it doesn’t check if the part is visually blocked, which would be really complicated to get precisely anyways.

You can input OverlapParams as well, if you want to only capture something specific, or maybe exclude your character, ect.