How can I find multiple parts from a player’s humanoid root part?
You can create a region3 centered around the humanoid root part and then use
Workspace:FindPartsInRegion3 to find parts in the region 3.
Or you can use the Rotated Region 3 Module if you want the region to be a sphere or any other shape(performance may vary).
Edit: also make sure to make the region3 nil once you are done with it.
could you show me how i can do this?
Hmm, I think it’s better you experiment with it first.
try doing this
--Require the rotated region 3 module
--Get the players humanoid root part CFrame
local humanoidRootPart = InsertPathToTheHumanoid here
local sphereRadius = Vector3.new(0,1,0)
local playerSphereDetector = RotatedRegion3.Ball(humanoidRootPart.CFrame, sphereRadius)
local allParts = RotatedRegion3:FindPartsInRegion3()
print(allParts[1])
--Gotta make the region 3 nil to garbage collect it since we are not using it anymore
playerSphereDetector = nil
is it possible i can do this without region3? and also have a variable that is the amount of parts that i want to see if they are the closest ones
Oh, if you already know which parts you want to find the distance you can do this:
okay, how can i do it with multiple parts like instead of finding the closest part, find more than just oen parts that are closer to the player
It is with multiple parts though, the code in it iterates through all the parts in the folder. Then it returns only the nearest part.
no thats not what i mean, i ewant to find multiple parts that are closest to the player
lets say i have 5 parts in workspace and i want to find 2 of the closest parts, i want a script that will print the 2 parts names
Hello there!
You can do this by getting the HumanoidRootPart and the Part magnitude.
This is a script in ServerScriptService.
local rs = game:GetService("RunService")
game.Players.PlayerAdded:Connect(function(player)--The player that joined
player.CharacterAdded:Connect(function(char) --The player character is loaded
while rs.Stepped:Wait() do
for i, v in pairs(workspace.Partsss:GetChildren()) do --This is a model of parts that u want to detect if the player is near it
if v.ClassName == "Part" then
local humrp = player.Character:WaitForChild("HumanoidRootPart")--Player humanoid root part
if humrp then
local pos = humrp.Position - v.Position--Getting the part and humanoidrootpart Position
local Magnitude = pos.magnitude --Getting the Magnitude
if Magnitude <= 20 then --Add any number you want
print(Magnitude)
v:Destroy()--Destroy the part if its near it
end
end
end
end
end
end)
end)
How can I find multiple nearest parts?
Yeah rotated region 3 supports this, and I believe is your best bet if you don’t know how many parts you are working with.
RotatedRegion3:FindPartsInRegion3(Instance ignore, Integer maxParts)
> returns array of parts in the RotatedRegion3 object
> will return a maximum number of parts in array [maxParts] the default is 20
> parts that either are descendants of or actually are the [ignore] instance will be ignored
However, another option you could do is to:
-
loop through the parts you want.
-
For each part measure the distance of each part to the player, And store it in a table
-
Sort the table in order of distance using a sorting algorithm
-
Select the parts you want from the table (example first 5 parts, which is in first 5 indices of the table that is obtained since the distances are sorted from lowest to highest)
That is very simple.
In the Workspace,make a folder and put the parts that you want to Detect if the player is near.
In the script line 5, Change:
for i, v in pairs(game.Workspace.Partsss:GetChildren()) do
To:
for i, v in pairs(game.Workspace.YOURFOLDERWITHPARTS:GetChildren()) do
Specify what exactly you want to do in your original post so that it’s not open to ambiguity to other users trying to help. I also want to point out that the Scripting Support Subcategory is not intended to request code to be written for you – you should’ve at least tried to search the devforum and other development-related media and wrote a script. If it doesn’t work, you can come here and people here will try to fix it
This can be done using Magnitude/Player:GetDistanceFromCharacter() and tables. Basically, you’d want to iterate over all the parts and make a new entry in the table, referencing the object and the distance from the player:
local Distances = {}
for _,v in ipairs(parts) do
Distances[#Distances + 1] = {Object = v; Distance = Player:GetDistanceFromCharacter(v.Position)}
end
Now that the entries are in the table holding the parts and their distances from the player, you can sort the table using table.sort. How it works is by iterating all possible combinations of pairs of entries and you can pass a function as an argument that’ll be used to determine the sorting order. Table sort expects the function to return true for the first entry of the combination to come before the second entry of the combination, otherwise the second will come before the first:
table.sort(Distances, function(a, b)
return a.Distance < b.Distance
end)
Obtaining the closest parts is simple – use the indices of 1 and 2 of the table and you can get the objects since the table has been sorted in order of parts closest to the player
Resources:
- Table (Lua data type)
- Table (library) (documenting table.sort)
- GetDistanceFromCharacter function
- Magnitude
I decided to recreate this, but it does not work when i try it with multiple parts.
code:
local function NearestParts(PartsToFind, Player)
local Table = {}
for i = 1, PartsToFind do
local NearestPart = nil
local Lenght = nil
for i, Part in pairs(workspace:GetChildren()) do
if Part:IsA("Part") then
if Part.Name ~= "Baseplate" then
local LenghtX = Player:DistanceFromCharacter(Part.Position)
if Lenght == nil or LenghtX < Lenght then
Lenght = LenghtX
for i, v in pairs(Table) do
if v ~= Part then
Part.Transparency = 0
table.insert(Table, Part)
else
Part.Transparency = 1
end
end
end
end
end
end
end
end
game:GetService("RunService").Heartbeat:Connect(function()
for _, player in pairs(game.Players:GetPlayers()) do
if player.Character then
local humanoidRootPart = player.Character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
wait()
NearestParts(10, player)
end
end
end
end)
The previous code that I gave, sorry since I misunderstood your question, was designed to only find the nearest part. This is because of this statement:
This if statement causes the for loop to ignore parts other than the currently closest part it has found in the for loop simply put.
I recommend following the scripting logic by @Rare_tendo which provides the resources needed for you to understand the code and not just copy-paste the previous threads answer that doesn’t exactly fit your problem. Sorry for being harsh I know it’s very tempting to want to instantly and quickly find the solution to the problems you are having troubled with, I do it too.
The logic for sorting is as summarized as follows.
-
loop through the parts you want.
-
For each part measure the distance of each part to the player, And store it in a table along with the table of parts.
-
Sort both tables (part table, and distance table) in order of distance using a sorting algorithm
-
Select the parts you want from the part table since it is now organized from closest distance to furthest distance from i=1 to i = 100…
many of the posts ive seen are iterating through the parts. This will create lag for the majority of places.
You can create a expanding bubble around the player and get the touching parts. Its the least hassle and wont lag your game out.
Yeah that is true that’s why I suggested region 3 initially but I believe OP is a newbie scripter who wants to find an easier solution/alternate solution so we started discussing for loops.
The code that i gave you works for multiple parts.
It is really simple to use.
Make a folder inside workspace and name it what you want,Insert the parts that you want to detect.
Screenshot:
The code that i gave you,In line 5 Change:
for i, v in pairs(game.Workspace.Partsss:GetChildren()) do
To the location of your folder that has the parts inside it.
You can test it if you want to see if it works, It works for me.
Code:
local rs = game:GetService("RunService")
game.Players.PlayerAdded:Connect(function(player)--The player that joined
player.CharacterAdded:Connect(function(char) --The player character is loaded
while rs.Stepped:Wait() do
for i, v in pairs(workspace.Partsss:GetChildren()) do --This is a model of parts that u want to detect if the player is near it. NOTE:Change the location to your folder that has parts inside it!!
if v.ClassName == "Part" then
local humrp = player.Character:WaitForChild("HumanoidRootPart")--Player humanoid root part
if humrp then
local pos = humrp.Position - v.Position--Getting the part and humanoidrootpart Position
local Magnitude = pos.magnitude --Getting the Magnitude
if Magnitude <= 20 then --Add any number you want
print(Magnitude)
v:Destroy()--Destroy the part if its near it
end
end
end
end
end
end)
end)
Can I make it so it prints more than one of the closest part? Like for example, I have 50 parts in the workspace, and I want to print multiple of the closest parts that I can change the amount of the closest parts with a variable.