How to retrieve a table of every object within view of camera

I’m trying to make a script where it grabs every object inside the player’s view (preferably in the form of a table) and when looping through the table; if it catches an object with a certain variable inside it, it will react to it.

I’ve tried searching the devforum but cannot find a matching answer.

Any help is appreciated!

1 Like

You can use something like this to check if a single part is on screen:

Then it’s a matter of looping through all the parts in workspace and checking if they’re on screen and have the variable in them.

It may also make sense to use tags (from CollectionService) instead of sticking variables in parts. Then you can directly call CollectionService:GetTagged and loop through the tagged pieces to check if they’re on screen.

1 Like

Maybe this will help.

2 Likes

The point of this thread is that I need to loop through a table to find the hitbox part, I don’t use a list of hitbox parts to detect.

1 Like
local Camera = workspace.CurrentCamera

function GetPartsInView()
   local parts = {}
   for i, obj in pairs(workspace:GetDescendants()) do
      local vector, isOnScreen = Camera:WorldToScreenPoint(obj.Position)
      if isOnScreen then
         table.insert(parts, obj)
      end
   end

   return parts
end

local partsinview = GetPartsInView()

Try this

Edit: WorldToScreenPoint’s isOnScreen bool will return true even if a part is behind another part but still within camera bounds, so if you only want parts that the player can see then maybe your going to want another method like raycasting

5 Likes

Thanks, although I had to do a quick repair to your function:

function GetPartsInView()
	local parts = {}
	for i, obj in pairs(workspace:GetDescendants()) do
		if obj:IsA("BasePart") then
			local vector, isOnScreen = Camera:WorldToScreenPoint(obj.Position)
			if isOnScreen then
				table.insert(parts, obj)
			end
		end
	end

	return parts
end

(It counted non-part objects including Terrain and Camera without the :IsA)

But one more question, if I wanted to detect parts that are within a certain distance, how would I do that?

2 Likes

Add a magnitude check with your :IsA()

if obj:IsA("BasePart") and (obj.Position - localplayer.Character.HumanoidRootPart.Position).Magnitude <= 50 then --50 is the range 
			local vector, isOnScreen = Camera:WorldToScreenPoint(obj.Position)
			if isOnScreen then
				table.insert(parts, obj)
			end
		end
2 Likes

Thanks, you deserve a medal because you are a saviour :+1:

(Yes, I ripped it off the internet.)

1 Like
local players = game:GetService("Players")
local player = players.LocalPlayer
local camera = workspace.CurrentCamera

local function getPartsInViewport(maxDistance)
	local partsInViewport = {}
	for _, part in ipairs(workspace:GetDescendants()) do
		if part:IsA("BasePart") then
			local distance = player:DistanceFromCharacter(part.Position)
			if distance <= maxDistance then
				local _, isVisible = camera:WorldToViewportPoint(part.Position)
				if isVisible then
					table.insert(partsInViewport, part)
				end
			end
		end
	end
	return partsInViewport
end

local parts = getPartsInViewport(100)
for _, part in ipairs(parts) do
	print(part.Name)
end
2 Likes