Let’s Make a 4X Space Game with Unity – Part 28 Building Ships with Turns 2
Hi Guys and welcome to part 28. In the last part we started a turn system so we can build ships in multiple turns. In this part we will connect up the UI so we display the number of turns.
I would just like to say a massive thank you to Creative-House.org (website here) for his generous donation which will pay for the site to run for the entire year!
Also a mention to my Patreon supporters thank you for your ongoing support I really do appreciate it.
On to the tutorial…
Let’s connect the UI first. Let’s do this in the GUIManagementScript. We already have a reference to our starbase panel so to get our content panel (the place where the ship buttons get put) is easy enough. At the top of the class declare a GameObject called content.
Add an Awake method and in that method find the Content object from starBasePanel using the GetComponentInChildren method. The component we are looking for is the vertical layout group as this is the component which sets the Content object apart from the other children. We need a .gameObject on the end because we are looking for the GameObject not the component itself.
Now we can make a new public void method called UpdateShipProductionUI. In it, add a for loop starting at 0 and ending when the count is equal to the number of children in content. Use the Transform.childCount function for this.
Note: I had a brain fart and called my method UpDateShipProductionUI and took some of the following pictures with it named this way. Ignore the capital D in the pictures and make it a small d instead.
To update we first need a reference of that text. Seeing as we have added two text components to our buttons (one to display ship and the other to show the number of turns left) we need to grab an array of all the text components in the children. Our prefab is set up so that the turn count text should be second in the hierarchy meaning the second text in the array should be in the last slot of this text array. To do this we use the GetComponentsinChildren function again, looking for the Text components.
We hit a bit of a wall at this point. We need to know how many turns left before the ships will be built but in order to do that we need a reference to the current planet selected. In the SolarSystem script declare a new public Planet called currentPlanet and give it get and protected set.
When we click on the planet and open up the planet panel we set current planet to that planet (in the Update Method).
We should also set it to null at the start of the game as well. Add an Awake method and set currentPlanet to null. While we are at it cut the find fleet manager line from the OnEnable to the awake. Its probably a little bit safer to have it here than in the OnEnable method.
We can now get our planet from our SolarSystemInstance. Head back to the GUIManagementScript. In the UpdateShipProductionUI method before the for loop declare a Planet called planet and set it equal to the currentPlanet in the SolarSystemInstance.
Now we can wrap our for loop in an if statement to check the planet’s production is more than 0 (it will always be that at the moment because we set the default to 2). We need to do this because we need to calculate the number of turns using the formula:
number of turns = (ship production value – starbase current production)/ planet production
If the planet production is zero we will get an error.
In our for loop declare a Ship called ship and set it equal to the planets starbase’s build cue at index i.
Everything is now there to calculate the number of turns. To do this we use the Mathf.CeilToInt function on the formula I told you above. This converts a float to an int as well as rounding it up. Why do we need to round up? Well what if it is going to take 2.2 turns to create a ship? We dont have 0.2 of a turn so it will be completed on turn 3 and the extra production put into the next item in the cue.
Now all we need to do is set the text to equal our number of turns. Remember the number text should be the second text in the array. However what if we need to add more text to the button in the future it might be better to always keep the number of turns as the last one in the array. So instead of specifying the index as 1 lets reference the last item in the array. We do this by putting array.length – 1 as the index.
If you hit play at this point you will probably get an error when advancing your turn. This is because we have not linked all our scripts yet. Open up the FleetManager script. In the BuildShip method after we make the new Ship called ship, add this ship to the current planets build cue. After that call UpdateShipProductionUI to get the correct number of turns for the ship being built.
Next open up the Galaxy script and in the StarOwnedMethod add the planet to the ownedPlanets list.
We just need to add the UpdateShipProductionUI to our build ship button OnClick, so that when the button appears the number will be correct.
Finally in the TurnManager script in EndTurn, call the UpdateShipProductionUI method after applying the production.
Now press play and add some ships to the production cue of our colonised planet. Click through the turns and the numbers should change to the number of turns. However at the moment all the ships are being built at the same time! This is not what we want we want the first in the cue to build, followed by the second, third etc… we will fix this in the next part.
And that, ladies and gents, concludes this part. In the next part, as well as making the change mentioned above, we will also set up our game so the cube ships only appear when all their production is complete.
Part 29 Building Ships with Turns 3 – Coming Soon