Hello! I recently made an orbital gravity script, taking things from a YouTube video called Coding Adventure: Solar System and adapting the equasion to use in Roblox with VectorForces. It works fine, when there is one small planet and a huge star object, the planet gets sucked into the star. However, as soon as I add another object, bigger than the planet, the force in both objects don’t make them move due to it trying to attract to both objects I’m assuming. Can anyone help me fix this?
Images:
Works:
Doesn’t work:
Code:
local RunService = game:GetService("RunService")
local bodies = workspace.Bodies
function updateForce(body, otherBody)
local bodyMass = body:GetMass()
local otherBodyMass = otherBody:GetMass()
local radius = body.CFrame.Position - otherBody.CFrame.Position
local scalarForce = (bodyMass + otherBodyMass) / radius.Magnitude^2
local force = radius.Unit * scalarForce
body.GravityForce.Force = -force
otherBody.GravityForce.Force = force
end
for _, body in pairs(bodies:GetChildren()) do
local gravityForce = Instance.new("VectorForce")
local attachment = Instance.new("Attachment")
attachment.Parent = body
gravityForce.Name = "GravityForce"
gravityForce.Attachment0 = attachment
gravityForce.Parent = body
end
RunService.Stepped:Connect(function()
for _, body in pairs(bodies:GetChildren()) do
for i, otherBody in pairs(bodies:GetChildren()) do
if otherBody ~= body then
updateForce(body, otherBody)
end
end
end
end)
Each body experiences one force due to the gravity of each other body. If a planet pulls the moon with some force, and the sun also pulls the moon with some force, the resulting force is the sun of those forces. That resulting force is what you need.
That means each body needs to look at every other body to figure out what the force needs to be.
That would look something like this:
function updateForce(body)
local resultingForce = Vector3.new()
for _, otherBody in pairs(bodies:GetChildren()) do
if otherBody ~= body then
local bodyMass = body:GetMass()
local otherBodyMass = otherBody:GetMass()
local radius = body.CFrame.Position - otherBody.CFrame.Position
local scalarForce = (bodyMass + otherBodyMass) / radius.Magnitude^2
local force = radius.Unit * scalarForce
resultingForce = resultingForce + force
end
end
--Don't need to set the GravityForce on the other body, because it also gets updated in the RenderStepped loop
body.GravityForce.Force = -resultingForce
end
RunService.Stepped:Connect(function()
for _, body in pairs(bodies:GetChildren()) do
updateForce(body)
end
end)
Happy to see someone else trying to do this kind of thing on Roblox as well.
If you need help with more accurately simulating an orbiting objects position as a function of time I am currently working on a script that simulates one-body orbits using Kepler’s equations.