DEV Community

Ioannis Apostolopoulos
Ioannis Apostolopoulos

Posted on

Creating A Planetary System Simulation in Unity 2D

I have always been interested in physics, initially physics concerning planets and how outer space travel works. This stemmed from an interest in a video game called Kerbal Space Program, and has since led me to discover many more fields of science, as I take physics as a course and am heavily interested in it. Another thing I am very passionate about is creating videogames, and I have managed to unluck that side of me through Unity and C#. I have created 3 released games, some with help, one on my own, and I plan on developing many more, it is a passion of mine. Recently I thought, what if I combined the concepts of gravitation in physics, as I had recently studied for it, and my passion for creating games. Hence, I decided to start a small project creating a basic simulation of a solar system in Unity 2D, utilizing my own functions that use Newtonian physics to simulate gravitation.

The initial objective or goal of this little simulation is to have two spheres that can attract each other by following Newton's law of gravitation:

Image description

Where:

  • M and m are the masses of the two planets or objects
  • G is the gravitational constant (6.67*10^-11)
  • r is the distance between the two planets/objects

First I set up a scene containing two spheres, with a RigidBody2D and a mass of 10 and 100kg.

Image description

I then created a script called Handle Gravity. I set out to make a function that followed Newton's law of gravitation. I created a method called AddGravity(), that took in the RigidBody2D of the attracted object, and the RigidBody2D of the attracting object. I first declared the gravitational constant (6.67*10^-11), and found the product of the masses times the gravitational constant G:

Image description

I then divided this by the distance between the two objects squared, which can be found by subtracting the two vectors (float vectorDistance = attracted.position - attractor.position;), and proceeded to use Unity's built in Vector3.magnitude to find the distance between the two objects. Now that I have the product of the masses, and the distance between the two planets, I can apply Newton's law of gravitation. I can also find the distance by using Unity's Vector3.normalized. This returns a vector with magnitude of 1, in the direction of the vector, which in this case is the vectorDistance vector. The normalized vector and magnitude of force are then multiplied together to get the vector for total force.

Image description

This total force is then applied onto the attracted object:
attracted.AddForce(totalForce);

To actually continuously apply this force onto affected objects, I created a list of RigidBody2Ds of the attracted and attractors, and looped through them, applying the correct force for each object. Since this is physics based, I continuously called the function in the FixedUpdate Unity method:

Image description

This code is then attached to a GameManager object, and the two RigidBodys are referenced in the Lists I created before. From this, these are the results:

Image description

You are not missing out by this only being an image, there is no movement. When I logged the totalforce, it was equal to zero.

I realized the issue moments later: since the gravitational constant is used for celestial objects of large mass, it effectively acts as a 0 in the multiplication at such low masses. To compensate for this, I thought of using the real masses of the earth and moon to see if that would fix the issue. The mass of Earth would be 5.972*10^24 kg, and the mass of the earth would be 7.342*10^22 kg. After inputting these masses, this is the total force recorded:

Image description

This of course is an improvement, but I realized that Unity puts a limit to the mass of its objects, at 1000000kg. To compensate for this, I thought to adjust the gravitational constant. I tried to calculate the in game G using the ratios of in game mass to real life mass, but for Unity2D, this is hardly tangible, as the gravitational constant G becomes even more insignificant, this is why I decided to play around with the values of G, ranging from 0.1 to 1.

Upon running the code, I found that the smaller planet quickly accelerated away from the other planet, mimicking two equal charges instead of masses. I could tell that this was a matter of the direction I was calculating.

I managed to fix this by changing the line:
Vector3 vectorDistance = attracted.position - attractor.position;
to:
Vector3 vectorDistance = attractor.position - attracted.position;

I realized this was wrong, cause since the force is acted on the 'attracted' body, the distance would be position of attracted - the position of the attractor, which would always be negative (position of attracted < position of attractor).

The next step would be to add an initial force to the smaller mass to allow it to orbit the larger one. I did this by applying a force in the start method:

Image description

Turns out that a force of magnitude 5 is not nearly enough, and thus I changed it to a force of -150 magnitude on the y axis. I also stopped the larger mass from feeling the gravitational force to keep the system on screen:

This short project has been a successful one, and due to my busy schedule, a quite enjoyable one. This was quite simple, so I do see myself moving into either tougher physics simulations in the future, or crafting a game out of this simulation or concept. But that is for another post. I will not post this simulation anywhere most likely, until I work on it further. Thank you to anyone who actually read through this!

The next steps for such a project would be mechanics such as collisions, visualizing orbits, and being able to manually add forces to objects.

Top comments (0)