Let’s Make a 4X Space Game with Unity – Part 12 Starting Spiral Galaxies
Hi guys and welcome to part 12. In the last part we added a selection icon so it was easier to see which object our mouse was over. In this part we will start to add a new type of galaxy to our game, spiral galaxies. This will probably take around about 3 tutorials to achieve and so do not think the picture above represents the finished article :).
Spiral galaxies (like the Milky Way) are made up from a number of arms which are wider towards the centre. The centre usually has a high density of stars and resembles a disc galaxy. To construct our spiral galaxy we will treat each arm and the central disc separately. In this part we will concentrate on the arms and in the next part we will work on the centre.
To begin with open up the Galaxy script and add a new method called CreateSpiralGalaxy. Make it public and void with nothing passed to it. Next in the Start method comment out the call the CreateGalaxy and call CreateSpiralGalaxy instead.
Like in our CreateGalaxy method we will need to create polar coordinates and then convert them into Cartesian coordinates to place our spheres. However unlike our disk/ring galaxies the position will not be completely random. Instead they are made up from a number of spirals.
The number of spirals reflects the number of arms the galaxy has. We should add numberOfArms to our Galaxy script as a public int. Make the default value 2.
The way we will tackle this is to create each arm one by one. To do this we need to know how many stars are in each arm.
In CreateSpiralGalaxy declare a new float called starsPerArm and set it equal to numberOfStars divided by numberOfArms. We need to make this into an int so declare a new int called starsPerArmRounded. Use the Mathf.RoundToInt method to set this value. Lastly we need to know the difference between starsPerArmRounded times numberOfArms and numberOfStars as when we round we could loose or gain stars. Call this one difference.
As we are creating each arm one at a time we will need to use nested for loops. One to keep track of the arm number and the other to track the star number. Use i as the letter for arm number and j for the star number.
So what’s next? Well we need to create the star data so create a new Star called star data. The name of the star is a little bit more complicated than in a disk galaxy because we are treating each arm individually. It will be “Star ” + (j + (starsPerArm * i). The number of planets will be the same as in our CreateGalaxy method using Random.Range.
Now we need an angle and a distance like we did for the disc galaxy. But what do we set them as? Let’s start with the angle.
Because we are dealing with multiple arms each arm will need to be offset from the other. Declare a new float for this called armAngle. We can easily calculate this angle as it will just be 2 * Pi divided by numberOfArms. We can then multiply it by i to apply the offset for each arm.
Next we need to think about each individual star. A spiral revolves around a point like a circle does so we need 2 * Pi in our equation. We can then separate the stars by an equal angle by dividing this by starsPerArm and multiplying by j.
Now we have two angles which need to be added together. Let’s add a new method in our PositionMaths script to handle this.Make it public static and return a float. Call it SpiralAngle and have it be passed two floats (armAngle and starAngle). Then simply declare a new float equal to the two passed floats added together. Don’t forget to return this value.
Return to the Galaxy script and in the CreateSpiralGalaxy method declare a new float called angle and make it equal to the method we just created with armAngle and starAngle passed to it.
We can now move on to our distance component for our polar coordinates. There are many different types of spiral with different equations for their distance component. If you are interested you can read about them here. However for this project we will use the square root of the star number + 1 as the main equation. The plus one is necessary as it looks a bit odd with out it (the first star on each arm is a fair way away from the other stars!).
We also need to add a multiplier as this returns very small spirals. From a bit of experimentation 4 * numberOfArms seems to be a good multiplier.
Lastly we also need to add our minimumRadius.
Great now we have an angle and a distance so all we need to do now is call PolarToCart method from PositionMaths and create a sphere in the new position using CreateSphereObject in our SpaceObjects script.
If we press play we get something like the picture below. We can see the spirals work but it doesn’t look much like a galaxy!
To fix this we need to randomise the angles of our stars a bit. Where we calculate angle add a Random.Range between + and -, Pi/(2*numberOfArms).
Now if we hit play again we get something like this:
This looks much better :).
One last thing before we wrap up this part of the tutorial. We need to seed our spiral galaxy like we did with our disk galaxy so add Random.InitState at the top of the method.
This seems like a good place to stop :). In the next part we will add our central mass of stars so it looks more like a real spiral galaxy and stop stars from colliding with each other like we did in our disk galaxies.
Scripts_for_part_12 (zip file)