↜ Back to home

My little solar system: 2D gravitational physics in Unity

By Ruben Droogh

Creating your own little universe to fly around in is a fun challenge for space nerds like me. In this blog, I will talk about the way we implemented gravitational physics in our game Orbinauts, what we learned from it, and what to watch out for.

The initial inspiration for this coding adventure was this great video by Sebastian Lague: Coding Adventure: Solar System. I can recommend this YouTube creator as a great source of inspiration. This guide assumes a basic understanding of working with Unity in C#.

The scope of this guide

In this guide, we will be making the following:

In 1-body gravitational physics, our spaceship is influenced by only one (planetary) body at a time, while in n-body physics, it is influenced by multiple bodies simultaneously. You might be surprised to learn that n-body gravity is easier to implement than 1-body, but we found that this is more confusing for players and a nightmare to visualize clearly in the UI.

The physics

To implement n-body gravity, all you need to do is apply Newton's law of universal gravitation, which is the following equation:

double F = (G * m1 * m2) / (r * r);

Where F is the force acted upon both objects, G the gravitational constant (more about that later), m1 and m2 the masses of both objects and r the distance between the objects. To apply this to your spaceship, simply loop through all gravity sources, calculate the force that the source exerts on the ship using the above function, add them together, and apply this sum to the spaceship.

We, however, want to apply 1-body physics. Our own little universe has its own little rules, and some of them do not match the real universe. One important one is the gravitational constant. This is basically the setting for how strong the gravity is in the universe. This is very much simplified, of course.* If you want to read more about it go check Wikipedia, you nerd. For the real universe, G equates to 6.6743 × 10^-11. We can make a constants class to access our own G, and we can play with it in real-time to get a value that feels right.

public static class AstroPhysics
{
    public static float G;
}

Our little solar system

Let's create a little solar system for our ship to fly around in. We're keeping it simple: a sun, and two planets orbiting it. We can simulate this in two ways:

  1. By applying the law of gravity on the planet, the same way as we do onto the spaceship, or
  2. By putting the planets "on rails"

The first option is more computationally expensive, but more realistic. It can also simulate some more interesting orbital phenomena, like two planets orbiting each other. The second option is cheaper, simpler, and we can make the orbital distances match the realistic speed by doing some fun maths. Let's do that one then.

First: let's make a script that defines a GameObject as a Gravity Source. It needs, for now, only one parameters: the mass. Basically how heavy the object is. You can assign any size you want, as long as it's consistent relative to the other bodies and your spaceship.

public class GravitySource : MonoBehaviour
{
    public float mass;
}

Let's make a sun: take a sprite of your choice and drag it into the scene. Give it the Gravity Source script and set the mass.

Now create some planets. Name them something fun and think of some cool lore around it (very important since you want your game to be cool). Place them into the scene at the distance from the sun you want them to orbit. Again, add the Gravity Source script and set the mass.

We want to make the planets orbit the star, and for that we need some code. Take a look at this snippet:

Mathf.Sqrt((AstroPhysics.g * centreGravitySource.mass) / this.radius);