Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

How do I optimize my Region3 player detection?

Asked by 4 years ago
Edited 4 years ago

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
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 User#32819 0 — 4y

1 answer

Log in to vote
3
Answered by
ben0h555 417 Moderation Voter
4 years ago
Edited 4 years ago

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.

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! Gey4Jesus69 2705 — 4y
Ad

Answer this question