# Orbit Mechanics  Months ago, around the start of DuskLight Studios, I wanted to create a game about flying around planets in orbit with each other. A game about exploration through space, adjusting your own orbit to move from planet to planet. I severely underestimated the difficulty of this.

## Elliptic path My first experiment in Unity included a single planet with a moon in orbit. The moon’s velocity was affected by the planet’s gravity, which varies in strength depending on distance to the planet. I couldn’t figure out the mathmatical formule to calculate the gravity’s pull, trying out faulty code I found online. It did result in an orbit, but it wasn’t right.

When a ship orbits a planet (and only that planet), it should be locked in an elliptic path. As long as it doesn’t accelerate in any direction, the ship will end up in the exact same position as it started at and eternally follow the exact same path. The first experiment did not achieve this, and I moved on to other projects to prevent wasting too much time.

## Gravitational pull

A couple of weeks ago, I gave it another shot. I found a quite interesting link providing me with several different solutions to orbital mechanics in code.

The Euler integration was easy to implement into a new Unity project. It started off in script; using the transform’s position, a velocity vector, and the gravitational pull to mimick the results. It worked, allowing me to iterate and improve upon the code.

Gravitational pull (g) equals to planet mass (m) multiplied by the square of distance between planet and ship (d^2): g = m * d^2

The function (present within the planet’s script) I currently use to calculate the gravitational acceleration:

public Vector3 GetGravity(Vector3 attract) {
Vector2 delta = transform.position – attract;
Return delta.normalized * ((mass * gravityConstant) / delta.sqrMagnitude);
}

Vector3 attract is the position at which the orbitting object is located.

Note that the calculations occur with Vector2 instead of Vector3, and that the square magnitude is used instead of the regular magnitude, both saving performance. Calculation of the square root of any number is much more CPU intensive than multiplications. Same goes for the Mathf.Pow(x) function.

## Unity Physics

Achieving orbit is great and all, but I needed the code to work with the built-in Unity physics. That way I could include realistic collisions with planets and asteroids. I quickly ran into a couple of weird problems, though.

Note that all calculations should be run within the FixedUpdate, so it runs in sync with the Unity physics simulation.

I had to remove my own velocity vector and start using the Rigidbody2D’s velocity instead. Normally you’d use the function body.AddForce(gravity) to accelerate the ship, which I did at first. This resulted in a steady but weird orbit that didn’t follow the elliptic path as it should, leading me to believe that using forces for gravity is a bad idea. There was no way to really know how much velocity would be gained if I added a certain amount of force. Add to this that gravity pulls all objects equally, regardless of object mass, it proved I needed a different solution.

Instead of forces, I decided to affect the velocity directly. (body is the Rigidbody2D)

gravity = planet.GetGravity(transform.position);
velocity = body.velocity;
velocity += gravity * Time.fixedDeltaTime;
body.velocity = velocity;