Let’s Make a 4X Space Game with Unity – Part 30 Getting Resources from Planets
Hi Guys and welcome to Part 30. In the last part we finished off our build ships UI and made sure ships were only built when the number of turns was up. In this part we are going to revisit our resource system and make it better as well as start looking at how we can start getting resources from planets.
I have an apology to make because I broke the game in the last tutorial. The last thing we did was remove the build ship method from the build ship button. This is wrong because now we have no way to add ships to the build cue in the star base! I don’t know what I was thinking, so please return the build ship button OnClick to how it is shown below.
Next we need to open the FleetManager script and add a new public void Method called CreateShip. This will take all the code that adds our ship to the build cue and takes our resources away.
We now need to pass the BuildShip method a Ship called ship. This means we need to go into the ApplyProduction method in the TurnManager script. When we call BuildShip we pass it the first ship in the cue.
Lastly we need to change the build ship button to use the CreateShip method instead.
Again I’m really sorry about that… I blame the beer I was drinking when I wrote the last tutorial :).
Let’s open the Resources script. Currently we have them represented by a number when we add and subtract them (1 = credits, 2= minerals etc…). While this works it is not very user friendly. Instead we are going to use an Enum.
An Enum is a data structure of named integers, which contain its own variables. It cannot inherit values from else where and it cannot pass inheritance. They allow user friendly names for things and are great for applications with a fixed amount of data. Examples of this would be days of the week, equipment slots on a character (head, chest, legs etc…) and resources like we need in our game.
At the top of the script, below the using statements but above the Resources class, add a public Enum called ResourceType. Add in Food, Minerals and Credits as well as any extra ones you decided to use.
Now we can now add another AddResources method under the other one (again public void), but instead of passing it an int for the type we pass it a resource type.
We then add a switch case very similar to the one above but we change the cases to a ResourceType instead of an int (see picture below because it will make more sense if you see it :))
Note: This now gives us the option to use either AddResource method. So we if need to add the amount to all resources at once we just use the one where we pass an int and pass it 0.
Open up the Planet script. We are going to add a public Resources class to the planet script called planetResources. In the constructor set this equal to a new Resources class with zero of all resources. We will be changing this in a minute but this will work as a place holder.
Add a new private (we only want to use it in the Planet class) Resource method called RandomiseResources and don’t pass it anything. This method will randomly assign values to the planets resources when the planet is created.
First we need 3 ints which are randomly assigned a value between a range (or more if you have more resources than the three I have). My range is going to be 0-3 but feel free to have whatever range you want. Name these ints after the resources you are setting.
Note: To make it more interesting, you could base this range on the planet type. For example gas giants don’t really have minerals so maybe we have a mineral range for them of between 0 and 1, but you could increase their credit output (maybe from selling the gas) to give players a reason to claim them. The food could be based on the race so for example if your race comes from a barren planet it would make sense to have more food on a barren planet for them. This might get a little complex however as different players in the game my see each planet differently.
We now create a new Resources called resources and set it equal to a new Resources passing it the numbers we just randomised. Return resources at the end of the method.
All we have left to do is change the code in the constructor so that planetResources equals this new function we made.
Let’s check this is working, open up the SolarSystem script and where we have the Debug.Log showing us the planet name and the type, add a new Debug.Log telling us the resources the planet has
Hit play and check everything is working.
Note: Because we have added more random checks to the game the planet and star system the player owns will have changed.
Great, but how do we receive these resources from our planets? Well we already have a list of player owned planets from our production system so we can loop through that and add their resources to our player resources.
To do this we first need a new void method in our TurnManager script called ApplyResources.
Add a for loop, with the limit of the number of planets in the list.
For each planet we need to add each of the resources to our player resources. Like in our ApplyProduction method declare a new Planet called planet and set it equal to the current planet in the loop. Then we take this planets resources and add them to our PlayerManager resources. Use the Enum AddResource so it is easy to read :).
We can add a Debug.Log here until we sort out the UI for our resources so we get some feedback on how many resources we have.
The last thing we need to do is call the ApplyResources method in our EndTurn method.
Hit play and check everything works.
So at this point I had a few bugs coming from a null reference exception on the owned planets star base. If you are getting the same bug Open up the Galaxy script and in the SetStarOwned method give the planet a new StarBase.
That concludes this part of the tutorial, in the next part we will start to add a basic resource UI so we no longer have to rely on the Console :).