In this article, I’m going to show you how to make a very simple simulation of planets orbiting the Sun, as well as rotating about their own axes. Even if you’re a beginner, you’ll be surprised how easy this is to set up. Just to set expectations, though: we’re keeping things simple to have fun and learn, so if you’re looking to create a realistic and accurate simulation of the Solar System, I’m afraid you’ve come to the wrong place.
Having said that, create a new 3D project with Unity3D, and let’s get to it! I’m using Unity3D 2021.1.10f1, which is one of the latest versions, but it’s also fine if you use an LTS version.
Creating the Sun and the Earth
From the GameObject menu (or by right-clicking in the Hierarchy window), click “3D Object” and then “Sphere” to create a sphere. Name it “Sun”. It should be positioned at the origin (0, 0, 0) by default, and that’s where we want it.
Repeat this process a second time, and name the second sphere “Earth”. From the Inspector window, set the “Y” component of its position to 5.
In order to make the Sun and the Earth look like the real deal, we’ll need textures. A texture is just an image that gets wrapped over the surface of a 3D object, so in our case we want a flat map of the Earth, and an equivalent for the Sun. You can find several on the internet, and in my case I’m using these Solar Textures which look pretty nice. The resolution doesn’t really matter, so pick whichever you like.
In the Project window in Unity3D, create three folders under Assets:
- Materials
- Scripts
- Textures
Drag the Sun and Earth textures from wherever you downloaded them onto the Textures folder you just created, and they will get added to the project there. Next, drag the Sun texture (in my case it’s called “2k_sun”) onto the Sun GameObject in either the Hierarchy or Scene windows. You’ll see that this automatically creates a material in the Materials folder, and the Sun sphere in the Scene window now actually looks like the Sun. Repeat the process for the Earth.
As a final touch, set the Sun’s scale to 2 (i.e. all of the X, Y and Z components). Press Play to admire your work so far:
Adding Orbit
We’d like the Earth to orbit the Sun, so let’s add a script to do that. Right click on the Scripts folder we created earlier, and select “Create” and then “C# Script”. Name the script “Orbit”. Double-click it in the Project window, or click “Open” in the Inspector window to open it using your default script editor (if you want to change this, go to Edit -> Preferences -> External Tools -> External Script Editor).
In the Update() method, add the following code to implement the orbiting behaviour:
void Update()
{
var sun = GameObject.Find("Sun");
this.transform.RotateAround(sun.transform.position, Vector3.forward,
100f * Time.deltaTime);
}
The first line gets a reference to the Sun GameObject via its name. The second line uses the RotateAround() method to make the Earth (this.transform
) rotate around the Sun (sun.transform.position
) around the axis that the camera is facing in (Vector3.forward
) at an angle of 100f * Time.deltaTime
.
Wait, why 100f * Time.deltaTime
? The Time.deltaTime is the time that elapsed since the last frame was rendered, so with each frame, the Earth will rotate a bit more around the sun. But Time.deltaTime
alone makes the orbit a little too slow, so I multiplied it by an arbitrary number, and by trial and error, I settled on 100f. This is actually a common practice, and can be done quite conveniently from the Inspector window if we make a small change to our code.
public class Orbit : MonoBehaviour
{
[SerializeField]
float speed = 100f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
var sun = GameObject.Find("Sun");
this.transform.RotateAround(sun.transform.position, Vector3.forward,
speed * Time.deltaTime);
}
}
By declaring a speed variable within the script’s class, marking it with the [SerializeField]
attribute, and then using it within the script, we’ve created a parameter that we can configure from the inspector.
Save the script from your editor, and go back to Unity3D, which will pause momentarily to reload and recompile the script. Drag the Orbit script onto the Earth in either the Hierarchy or the Scene window, and you will see it gets added as a component in the Inspector window. Interestingly, you will also see the Speed parameter:
If you click Play, you should now see the Earth orbit the Sun. You can also change the value of Speed (even while the game is running), see what difference it makes, and adjust it until you are happy.
Adding Rotation
To make the Earth (and, later, the Sun) spin around its own axis, we just need to follow the same steps as for the Orbit functionality, with a slight change to the script.
- Add a new script called Rotation to your Scripts folder.
- Open the script.
- Add the code below in the
Update()
method. - Drag the Rotation script onto both the Earth and the Sun.
void Update()
{
this.transform.RotateAround(this.transform.position,
Vector3.up, 200f * Time.deltaTime);
}
Here, the Earth or the Sun (this.transform
) will spin around itself (this.transform.position
) about the Y-axis (Vector3.up
) at an angle of 200f * Time.deltaTime
. Again, the choice of speed for the angle is arbitrary. As with Orbit, you can expose it to the Inspector and adjust it if you like.
Note that it probably makes sense to use Prefabs rather than attaching the script to each GameObject, but since we don’t have many, I prefer to keep things simple in this particular example.
If you press Play, you should now see the Earth orbiting around the Sun, while both spin independently at the same time.
Finishing Touches
In this section, we’ll make a few tweaks to the project settings to make things look a little nicer.
First, let’s disable the Skybox. To do this, open the Window menu, then click “Rendering” and Lighting:
In the Lighting window, switch to the Environment tab. The Skybox Material has a value of Default-Skybox. Click on the little circle next to that value and it select None from the new window that comes up.
Changing the Skybox has changed the fields in the Environment tab of the Lighting window. There is now an Ambient Color field. Set its value to white (by clicking the top-left part of the colour-picker square, or by setting each of the (R, G, B) values to 255. This makes the objects in the scene somewhat brighter:
Next, we’ll get rid of the annoying blue background colour, which looks as odd in outer space as the Skybox. To do that, select the Main Camera from the Hierarchy window, click on the value of its Background property, and set it to black by either clicking on the bottom portion of the colour-picker square, or by setting each of the (R, G, B) values to zero:
The last thing that’s looking awkward is the lighting: we have a Directional Light that came with the project template, and it’s illuminating both the Sun and the Earth. Delete it.
By either clicking the GameObject menu or else right-clicking inside the Hierarchy window, select Light -> Point Light to create a light that gives off light in all directions.
If you press Play, you’ll notice that the light is a little bit weak, so bump up its Intensity to 10. Then you should see a highlight shine off the Earth.
Finally, to make things a little crazier, I suggest adding another planet, such as Venus. To do this, follow the same steps you took when creating the Earth, with a few differences:
- Create a new sphere, and name it “Venus”.
- Set the Y component of its Position to 3.
- Find an appropriate texture and drag it onto the Textures folder.
- Drag that texture onto the Venus GameObject in either the Hierarchy or Scene window.
- Drag both the Orbit and Rotation scripts onto Venus.
- In the Inspector window, change the Speed setting on the Orbit script so that it is faster than the Earth’s speed, e.g. a value of 150.
Press Play and watch as Earth and Venus orbit the Sun with different speeds!
Going Further
This simulation, while very simplistic and not really representing the real behaviour of heavenly bodies, is a fun little exercise showing what you can do in Unity3D with very little effort. There are lots of ways you can take this further. Here are a few ideas:
- Learn about Prefabs, use them to create a template for the planets, and create the remaining planets of the Solar System.
- Add the Moon orbiting the Earth. Use the same Orbit script, but modify it so that you can plug which GameObject is orbited via the Inspector.
- Instead of specifying a different speed for each planet, try to calculate it based on the distance between the planet and the Sun.
- Tilt the Earth so that it rotates on something closer to its real axis.
- Experiment with elliptical orbits.