Hello. I am working on a script that gets the center of mass of a model. It goes through every part and gets its average position (and does a little bit of multiplying here and there to add the mass of each part in). For some reason, the marker test item I’m using is not at the exact location as it should be. Here is the code and my problem.
local plr = game.Players.LocalPlayer.UserId
function getcenterofmass(model)
local mass = Vector3.new(0,0,0)
local num = 0
for i, v in pairs(model:GetDescendants())do
if v:IsA("BasePart") then
local mass2 = v.Mass
local wholenumber = math.floor(mass2)
local decimal = mass2-math.floor(mass2)
if wholenumber ~= 0 then
for i = 1,wholenumber do
num += 1
mass += v.Position
-- table.insert(mass,(#mass+1),v.Position)
end
end
if decimal >= 0.025 then
num += 1
mass += (v.Position*decimal)
end
--table.insert(mass,(#mass+1),v.Position*decimal)
end
end
local final = mass/num
mass = Vector3.new(0,0,0)
num = 0
return final
end
local part = game:GetService("ReplicatedStorage").Content.PlotIndicator:Clone()
part.Parent = workspace.Storage
part.Position = getcenterofmass(workspace.Plots:WaitForChild(plr.."_Plot"))
game:GetService("RunService").Heartbeat:Connect(function()
--if part.Transparency == 0 then
part.Position = getcenterofmass(workspace.Plots:FindFirstChild(plr.."_Plot"))
-- end
end)
![image|690x387](upload://7oJNZ6HQzvdoVEkwWEheq7oiLvk.jpeg)
I’d like to note, that I think you can use a function like: “model.CenterOfMass”.
Otherwise we could come up with an artificial way of doing this, by calculating the area of objects and placing them on a table to find its center. This is useful because its very fast. Depends on if its on client or server though.
Here’s the difference between both threads of code.
IN THE GAME
local plr = game.Players.LocalPlayer.UserId
function getcenterofmass(model)
local mass = Vector3.new(0,0,0)
local num = 0
for i, v in pairs(model:GetDescendants())do
if v:IsA("BasePart") then
local mass2 = v.Mass
local wholenumber = math.floor(mass2)
local decimal = mass2-math.floor(mass2)
if wholenumber ~= 0 then
for i = 1,wholenumber do
num += 1
mass += v.Position
-- table.insert(mass,(#mass+1),v.Position)
end
end
if decimal >= 0.025 then
num += 1
mass += (v.Position*decimal)
end
--table.insert(mass,(#mass+1),v.Position*decimal)
end
end
local final = mass/num
mass = Vector3.new(0,0,0)
num = 0
return final
end
local part = game:GetService("ReplicatedStorage").Content.PlotIndicator:Clone()
part.Parent = workspace.Storage
part.Position = getcenterofmass(workspace.Plots:WaitForChild(plr.."_Plot"))
game:GetService("RunService").Heartbeat:Connect(function()
--if part.Transparency == 0 then
part.Position = getcenterofmass(workspace.Plots:FindFirstChild(plr.."_Plot"))
-- end
end)
IN THE TEST PLACE
local part = Instance.new("Part",workspace)
part.Anchored = true
part.Size = Vector3.new(3,3,3)
part.Material = Enum.Material.Neon
function getcenterofmass(model)
local mass = Vector3.new(0,0,0)
local num = 0
for i, v in pairs(model:GetDescendants())do
if v:IsA("BasePart") then
local mass2 = v.Mass
local wholenumber = math.floor(mass2)
local decimal = mass2-math.floor(mass2)
if wholenumber ~= 0 then
for i = 1,wholenumber do
num += 1
mass += v.Position
-- table.insert(mass,(#mass+1),v.Position)
end
end
num += 1
mass += (v.Position*decimal)
--table.insert(mass,(#mass+1),v.Position*decimal)
end
end
return mass/num
end
game:GetService("RunService").Stepped:Connect(function()
part.Position = getcenterofmass(workspace.Model)
end)
We can still avoid doing it every heart beat by toggling the transparency of the models locally.
Just a suggestion, but I find it fun to interact with other players in plane games. A lot of them do this, like Plane Crazy, Pilote Training Flight Simulator and Project Flightpoint.