What is the best way to simulate gravity?

Hi devs,

I’m scripting a game with planets and astroids.
I want it to orbit other objects, or if objects get to close they collide.

How can I make this?

– And will it need to be in “LocalScripts” or “ServerScripts”

5 Likes

I found this tutorial using line forces:
Simulating Planetary Gravity using Line Forces! - Roblox Studio - YouTube
It seems pretty helpful, you should check it out!

2 Likes

Works pretty well and all but,
the problem is there needs to be a part under the planet or moons.

Without the part planets and moons will just fall into the void. I’m also using models as the planets.

My goal is to make planets orbit the sun and moons orbit planets.

set the workspace gravity to 0

I want it to orbit other objects, or if objects get to close they collide???

In your script set workspace.Gravity = 0. That will keep objects from falling into the void. Then, your line forces will act as the gravity for the parts.

1 Like

You could also program all of the math in a script. I did that once, and the result was good, however line forces are more simple. If you want more freedom however, over things like the constant G, programming it yourself it a good route.
This is the equation for Newtons Law Of Universal Gravitation:

F = G * ((m1 * m2) / r2))

Where G is the gravitational constant:

G =  6.673e-11

and m1 is the Mass of the first object, and m2 is the Mass of the second object.

m1 = object1.Mass
m2 = object2.Mass

and r1 is the distance between the two bodies:

r1 = (object1.Position - object2.Position).magnitude

You can then bind that to RenderStepped, and apply the forces using a BodyForce, with the direction being the lookvector of a CFrame facing the object being orbited.

forceVector = CFrame.lookAt(object1.Position, object2.Position).LookVector * F

Something like what is shown above should work.

Edit: You also don’t need to use BodyForce, if you want to leave the workspace gravity on and walk around the place, you can just update the object’s position frame by frame, and change them according to the forceVector, like so:

object1.CFrame += forceVector
5 Likes

Thank you so much, this helps a lot!

I’m trying to do the same thing, and I have a script which loops over every child in a folder inside workspace which contains planets, and creates a line force from each one’s center toward some target.
I want to get that target to be every other child of the folder, and I want it to update as the game runs.
So far I have this:

local PlanetaryArray = workspace.Bodies:GetChildren()
local G = .67

local Target = workspace.Sun --Note here that the target is fixed for every body. I want it to shift between each sibling inside the folder.
for i = 1, #PlanetaryArray do
Planet = PlanetaryArray[i]
print(Planet)
local Mass = Planet.Mass
r = ((Planet.Position - Target.Position).Magnitude)
force = G * ((Planet.Mass * Target.Mass)/ r^2)

LineForce = Instance.new("LineForce")
APofPlanet1 = Instance.new("Attachment")
APofPlanet1.Parent = Planet
APofPlanet1.WorldPosition = Planet.Position
APofPlanet2 = Instance.new("Attachment")
APofPlanet2.Parent = Target
APofPlanet2.WorldPosition = Target.Position
LineForce.Magnitude = force
LineForce.ApplyAtCenterOfMass = true
LineForce.ReactionForceEnabled = true
LineForce.Attachment0 = APofPlanet1
LineForce.Attachment1 = APofPlanet2
LineForce.Parent = Planet

end

–now this is all well and good, but it doesn’t update to reflect the movement of the objects.

2 Likes