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
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.