# How do I get the middle of multiple parts?

I want to get the middle of these eight blocks, which is the red circle. Just know when I click run, the blocks act like a soft-body cube, and I’m trying to get the middle of all eight blocks.

2 Likes

Well, this only utilizes 2 of the parts, but this should work.

``````local parts = {} -- all of the parts

local part1
local part2

for i,p1 in pairs(parts) do
for i,p2 in pairs(parts) do
if p1.Position.X ~= p2.Position.X and p1.Position.Y ~= p2.Position.Y and p1.PositionZ ~= p2.Position.Z then
part1 = p1
part2 = p2
end

if part1 and part2 then break end
end

if part1 and part2 then break end
end

local pos = (part1.Position + part2.Position)/2``````

Do you know how I can make this work with eight parts?

Well, you don’t need to utilize all of the parts, but sure.

``````local parts = {} -- all of the parts

local pos

for i,part in pairs(parts) do
if pos then
pos += part.Position
else
pos = part.Position
end
end

pos /= #parts``````

Couldn’t you do this like finding the average? Add all the part’s X position, then divide by the number of parts. Then do that for the Y and Z. Right?

You could find the average position of all 8 parts shown in the picture which would be the same as finding where that red dot is.

``````local Parts = {} --// Your Parts

--// Variables
local FinalPosition = Vector3.new(0, 0, 0)

--// Loops through the parts' positions and adds them up for later use
for i = 1, #Parts, 1 do
FinalPosition += Parts[i].Position
end
FinalPosition /= #Parts --[[ Divides the total by # of parts to
find the average/middle position between all parts' positions]]

print(FinalPosition) --// The result
``````
1 Like

This is very odd, @deafaultyboii1324 @Kaid3n22 both scripts get the same result, and the red ball is very offset-ed from the center.

A few questions:

Where are the white dots you mentioned in your original post?

What parts are you using on the `Parts` variable?

1 Like

The white dots move around, like its an unanchored cube. The parts I’m using is all eight white dots.
sorry for the late reply

something like this? (I have not tested this)

``````local Parts = {} -- array of parts
local X = {}
local Y = {}
local Z = {}

for i, Part in ipairs(Parts) do
table.insert(X, Part.Position.X)
table.insert(Y, Part.Position.Y)
table.insert(Z, Part.Position.Z)
end

local MaxX = math.max(table.unpack(X))
local MinX = math.min(table.unpack(X))

local MaxY = math.max(table.unpack(Y))
local MinY = math.min(table.unpack(Y))

local MaxZ = math.max(table.unpack(Z))
local MinZ = math.min(table.unpack(Z))

local Middle = Vector3.new((MinX + MaxX) / 2, (MinY + MaxY) / 2, (MinZ + MaxZ) / 2)
``````
1 Like

The lazy way of doing this is to put the parts in a model and get the model’s Pivot

``````local function GetMiddlePosition(Parts : {Part}) : Vector3
local Model = Instance.new("Model")
Model.Parent = workspace

local Stuff = {}

for i, Part in pairs(Parts) do
table.insert(Stuff, {
["Instance"] = Part,
["Parent"] = Part.Parent
})

Part.Parent = Model
end

local PivotPosition = Model:GetPivot().Position

for i, Thing in pairs(Stuff) do
Thing.Instance.Parent = Thing.Parent
end

Model:Destroy()

return PivotPosition
end
``````
``GetMiddlePosition(workspace.Part1, workspace.part2 ... more thingies)``

No problem!

Have you welded the 8 parts together? Could you provide a screenshot of the parts and their descendants in the explorer?

MacOS: CTRL + CMD + SHIFT + 4, click and drag
Windows: Open the Snip & Sketch app, capture the screenshot, and press the copy button (top right corner)

1 Like

Well it’s a lot more complicated than just welded parts, they are all held by 28 springs in total. Each point is connected to each other point.

Do these parts hold a similar shape similar to a cube/the shape formed by the parts shown in your original post?

The script finds the average position among all 8 parts, which means if one part is far away from the others, then the position/red dot is going to be far away from the other 7 parts.

1 Like

Yes, when it is still it is basically a perfect cube

The absolute position/middle position might change from when the script gets the position of all 8 parts and when the loading screen disappears.

You could try setting the red dot’s position later or constantly update its position with `game:GetService('RunService'):Heartbeat()`(may not be the most performant based on what you need).

1 Like

I already have put it in the heartbeat loop I have.

I don’t see anything wrong here. Just for testing, what happens if you anchor those 8 parts and run the game?

1 Like

Sorry the quality is dog water, I lowered my bitrate to hell because obs was giving me gigantic file sizes, but I fixed it now.

``````function GetCenter(partList)
local min = nil
local max = nil
for _,i in pairs(partList) do
if not min then
min = i.Position
else
if i.Position.X < min.X then min = Vector3.new(i.Position.X,min.Y,min.Z) end
if i.Position.Y < min.Y then min = Vector3.new(min.X, i.Position.Y,min.Z) end
if i.Position.Z < min.Z then min = Vector3.new(min.X,min.Y,i.Position.Z) end
end
if not max then
max = i.Position
else
if i.Position.X > max.X then max = Vector3.new(i.Position.X,max.Y,max.Z) end
if i.Position.Y > max.Y then max = Vector3.new(max.X, i.Position.Y,max.Z) end
if i.Position.Z > max.Z then max = Vector3.new(max.X,max.Y,i.Position.Z) end
end
end

local center = ((max-min)/2)+min
return center
end

local tab = workspace.Folder:GetChildren()
local center = GetCenter(tab)

local marker = Instance.new("Part")
marker.Size = Vector3.new(1,1,1)
marker.BrickColor = BrickColor.Red()
marker.Parent = workspace
marker.Position = center
``````
3 Likes