+1 vote

I am trying to make a simple planetary simulation in 2D space where every RigidBody2D is acting as a "celestial body". For some reason, when I start the simulation with 2 bodies with the orbiting one being 10x lighter, but giving it a predefined velocity it starts to orbit. However, this orbit only lasts for half (in this case only a quarter of) an orbital period, after which it just accelerates away from the other body. The weird thing is, it doesn't matter which side I am starting on, it always behaves this way.

Planet starts orbiting from left, when it reaches halfway point it accelerates away
Planet starts orbiting from right, when it reaches halfway point it accelerates away
After the planet completes half an orbit and crosses the x-axis it starts to accelerate away.

Code handling the gravity:

for child1 in get_children():
    for child2 in get_children():
    if child1 != child2:
        distance = child2.position - child1.position;
        force = ( (G * child1.mass * child2.mass) / (pow(distance.length(), 2)) );
        child1.add_force(Vector2(0, 0), force * distance.normalized());

I know I don't have to implement "radial gravity" myself, though when working with Area2D's and Gravity Points I also ran into some troubles:
1. If I have big constelations, how big should I make my Area2D? After a while I just got insecure about the size...
2. I'd like to later add a preview of which orbit an object will take. Furthermore I'd like to automatically place an object at an circular orbit to its parent. To calculate these things I need values like the G constant, however, I found no documentation for how Godot does handles gravity online and attempts at calculating it myself were fruitless.
I guess Godot uses some other way I am not aware of to simulate "point gravity". If somebody could point me towards documentation for this or explain it to me I would be delighted.

Hope anyone can help me or even just point me to some tutorial or other resource which could help me wrap my head around these subjects, I just had troubles finding the information I was looking for online.

in Engine by (20 points)

1 Answer

+2 votes
Best answer

add_force() is cumulative. You're adding more and more forces to the body with each iteration. You need to change the total force, not add to it.

If you want "real" values you can use real numbers from the planets, which you can get like these: https://nssdc.gsfc.nasa.gov/planetary/factsheet/ Otherwise you're inventing your own physics and will have to painstakingly tweak G until you get something that produces circular orbits. Using Area2D is much easier.

If you want interactions between the bodies, not just around the central sun, then google the "three body problem" to see why that's going to be a problem. You might need to look into other integration methods since Keplerian orbits won't work.

Or, if you just want circular orbits, forget all this calculation, which is never going to work well over time due to floating-point error. Just add your planet as a child of another node and rotate that node. It's one line of code and will always be a perfect circle.

by (21,930 points)
selected by
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.