Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do I optimize my Region3 player detection?

I'm trying to make a mock auto duels for practice, as the applicability of using Region3s extends far beyond that scope. The issue I'm having is that the system has troubles detecting the player's character, and, probably more consistently, detecting when the character leaves the region.

Server Script:

local Players = game:GetService("Players")
--------------------------------------
local Arena = workspace.Arena
local Room = Arena.Room
local Spawns = Arena.Spawns
local Pads = Arena.Pads
local StatusBoard = Arena.StatusBoard
--------------------------------------
local Regions = {}

for i,v in pairs(Pads.Team1Pads:GetChildren()) do
	local SelectedPad = v
	Regions[i] = {Pad = v,Area = Region3.new(SelectedPad.Position,Vector3.new(SelectedPad.Position.X,SelectedPad.Position.Y + 12.9,SelectedPad.Position.Z))}
end

for i,v in pairs(Pads.Team2Pads:GetChildren()) do
	local SelectedPad = v
	Regions[i + 3] = {Pad = v,Area = Region3.new(SelectedPad.Position,Vector3.new(SelectedPad.Position.X,SelectedPad.Position.Y + 12.9,SelectedPad.Position.Z))}
end

while true do
	wait(.1)
	for i,v in pairs(Regions) do
		local Parts = workspace:FindPartsInRegion3(v.Area,Pads,math.huge)
		for _,Part in pairs(Parts) do
			local Character = Players:GetPlayerFromCharacter(Part.Parent) 
			if Character then
				v.Pad.BrickColor = BrickColor.new("Really red")
			else
				v.Pad.BrickColor = BrickColor.new("Medium stone grey")
			end
		end
	end
end

As I mentioned, the above code does work. It simply doesn't work well, and I'm unsure of what else I can do to optimize it. Any help would be greatly appreciated.

Edited Code

local Players = game:GetService("Players")
--------------------------------------
local Arena = workspace.Arena
local Room = Arena.Room
local Spawns = Arena.Spawns
local Pads = Arena.Pads
local StatusBoard = Arena.StatusBoard
--------------------------------------
local Regions = {}
local PlayerRoots = {}

Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local Root = Character:WaitForChild("HumanoidRootPart")
		if not PlayerRoots[Root] then
			table.insert(PlayerRoots,Root)
		end
	end)
	Player.CharacterRemoving:Connect(function(Character)
		local Root = Character:WaitForChild("HumanoidRootPart")
		for i,v in pairs(PlayerRoots) do
			if v == Root then
				table.remove(PlayerRoots,i)
			end
		end
	end)
end)

for i,v in pairs(Pads.Team1Pads:GetChildren()) do
	local SelectedPad = v
	Regions[i] = {Pad = v,Area = Region3.new(SelectedPad.Position,Vector3.new(SelectedPad.Position.X,SelectedPad.Position.Y + 12.9,SelectedPad.Position.Z))}
end

for i,v in pairs(Pads.Team2Pads:GetChildren()) do
	local SelectedPad = v
	Regions[i + 3] = {Pad = v,Area = Region3.new(SelectedPad.Position,Vector3.new(SelectedPad.Position.X,SelectedPad.Position.Y + 12.9,SelectedPad.Position.Z))}
end

while true do
	wait(.1)
	for i,v in pairs(Regions) do
		local Parts = workspace:FindPartsInRegion3WithWhiteList(v.Area,PlayerRoots,math.huge)
		if #Parts == 0 and v.Pad.BrickColor == BrickColor.new("Really red") then
			v.Pad.BrickColor = BrickColor.new("Medium stone grey")
		end
		for _,Part in pairs(Parts) do
			local Player = Players:GetPlayerFromCharacter(Part.Parent) 
			if Player then
				v.Pad.BrickColor = BrickColor.new("Really red")
			else
				v.Pad.BrickColor = BrickColor.new("Medium stone grey")
			end
		end
	end
end

1 comment

1

Hey, I just made a topic on the devforum asking for a substitute for while loops, I'll be looking at this question in case it gets a good answer, and you can look at the topic in case someone asnwers it: https://devforum.roblox.com/t/how-would-i-detect-players-in-a-certain-region3-without-the-use-of-while-loops/831960

1 answer

✓ Accepted answer

Use FindPartsInRegion3WithWhitelist with only the HumanoidRootPart's of the characters. This limits how many parts roblox is checking by a great magnitude (Depending on the parts in workspace), therefore reducing the calculation cost greatly. However, if this still does not fit your needs, I suggest simply doing Vector.magnitude math to create a sudo-sphere hitbox of sorts around a certain point checking only HumanoidRootParts, this'll be even less costly than a region3.

1 comment

0

That worked out pretty well (see my edited code above). I'll still look into using magnitude as a more efficient method, but you helped a bunch. Thanks!

This discussion is preserved as it was. New answers, comments, and votes are closed.