Wednesday 26 October 2016

Zelda Style Life System Unity Tutorial – Part 6 of 10

Zelda Style Life System Unity Tutorial - Part 6 of 10



The end result of the full tutorial.

At the end of Part 6 we will have produced this (See image 1.0).
Image 1.0

Before you start you should know these things:

You should have gone through and completed ‘Part 5’ of this tutorial before going any further. If you find yourself not understanding some of the terminology or code of the tutorial I would also recommend going through the previous tutorial to get up to speed. I will leave a link to it below to go through at your leisure.



http://joseph-easter.blogspot.com/2016/09/zelda-style-life-system-unity-tutorial.html

If you follow this tutorial and find I am moving too fast or if you don’t know the things in the list above, I would recommend getting up to speed and then come back to this tutorial when you are ready.

Links to Parts 1 - 10 of this tutorial series:

Part 1

Part 2

Part 3

Part 4

Part 5

Part 7

Part 8

Part 9

Part 10


With this tutorial if you want to convert this into JavaScript by all means do so but it may be easier for you to follow this in C# and stick with the language of the tutorial to make it easier.

PROJECT RESOURCES: At the bottom of the post there is a download link to a zip file. This files includes all files needed to follow Part 6 and the completed project file of Part 6.


In this part we will work on adding some live interactivity to our life system. Specifically added a few buttons to take away and add some health to see our code in action. In Part 7 we will work on updating the lives and having multiple health values per life icon.


We will:

  • Add a few buttons to our UI canvas
  • Assign the ‘Modify Health’ function to them
  • Parse each button a different value
  • Add ‘Update Lives’ function to buttons to reflect the current health value


Step 1: – Creating the Buttons

To start off we will do something easy. We will add a few buttons to our Canvas, three to increase our health value, one each set at ‘1’, ‘2’ and ‘3’, and another three to take damage at the same amounts.


To do this we will selected our ‘LifeSystemManager’, then create a button ‘Create’ -> ‘UI’ -> ‘Button’. Position this somewhere one the left side of the screen but not covering the ‘LifeSystemManager’ game object. I have positioned mine as in the image below, check figure 1.0.




Figure 1.0:
The RectTransform position is: X:-195, Y: 47, the anchor point set to middle, centre.



The next thing to do is keep everything organised. With the buttons on the left side of the screen, these will be used for increasing our health variable, and the buttons on the right will be used for decreasing the same value.


On the left side rename the button UI object to ‘Add1HealthBtn’. This is ok but we need to label what the button does. With our button, a text object is a child of our button, with the ‘Text’ UI element selected go to it’s text component and change the text in the box from ‘Button’ to ‘Add 1 Health’. (See figure 1.1).




Figure 1.1



Good we have the basic done and have created a button. We will create more later but this will do for now.


Step 2: - Adding Health

The next thing we need to do is add functionality to the button. Because this button is adding health we will assign the ‘AddHealth’ method to it. To do this we go to the ‘Button’ script on our button, and where it say’s ‘OnClick’ we will click the mini button wit the ‘+’ on it. This is basically a delegate that can be accesses via the inspector. A delegate is more or less like variable but it can only store functions. (See figure 1.2)



Figure 1.2



When we add a space for a function a variable appears. We can drag an object or any kind of script into it (including the same object the button is attached to).

We will drag in our ‘LifeSystemManager’ into the variable on the left. (See figure 1.3)



Figure 1.3



You may have noticed a drop down list or enum to the right is now available to us which says ‘No Function’. This enum will list all script available to us, and from there all of the public functions available to us in those scripts (only those which return ‘
void’ though). First we need to go to our code and make the function public.


Code:


public void AddLives(int n)
{
   for (int I = 0; I < n; i++)
   {
      Image tempImg = Instantiate(lifeImg, 

                                  transform.position, 
                                  transform.rotation) as Image;
      tempImg.transform.parent = transform;
   }
}



Then we click on the enum, choose the ‘LifeSystem’ script, then choose ‘
AddLives’ from the list of functions. (See figures 1.4 and 1.5).



Figure 1.4



Figure 1.5



We need to create a function for instantiating the ‘lifeImg’ game object, and place our code in there. For now we will call our function ‘
AddLives’.

Now have have chosen the ‘
AddLives’ method you have have noticed another field appear containing a ‘0’. This field is similar to a public variable. This field is here in case you want to parse your function any variables. This field is dynamic so if your function takes another type like strings you parse those through as well. We will replace the ‘0’ with a ‘1’ for this button, then run our code. (See figure 1.6)



Figure 1.6
I have just clicked to add another ‘lifeImg’, max icons per row set to 4.



Then respectively add a reference to it in the ‘
Start’ method. If we enter ‘Play’ mode, the behaviour of our code will not have changed, we’ve made it easier to read and more usable.


Step 3: - Taking Damage


Now we can add health at any time we need to be able to take damage and represent this on screen by removing a health icon. We will do two things, create a new button, rename it to ‘Remove1HealthBtn‘, change the text label to ‘Take Some Damage’, and move it to the right to the previous button. (See figure 1.7)




Figure 1.7
RectTransform positions, X: -17.8, Y: 47.



Now the next thing we need to do is create a method in which we can take some damage and reduce how many lives are on screen (and later a health variable). We will do this by creating a public method called ‘
ModifyLives’. For the time being this method will be pretty simple, but in Part 7 we will add more to it for extra functionality over the image icons. We will place this new method below ‘AddLives’.

In this new method we want to tell it the number of lives we will be modifying, so we will parse it an ‘
int’ called ‘amt’. At the top of the script we need to create another ‘int’ variable called ‘currentHealth’ to keep track of our health. In this method we add ‘amt’ to ‘currentHealth’ using the incremental operator.

Then we will need to update the ‘currentHealth’ variable at the end of ‘AddLives’ as this will update every time we add a life. With ‘ModifyHealth’ we are adding two values, this means that if we parse it a negative value, it will subtract ‘amt’ from current health as adding a negative value does that. Now to check that our code works we will print ‘currentHealth’ via ‘Debug.Log’, then assign this function to the ‘Remove1HealthBtn’.


Code:


public int currentHealth;

public void AddLives(int n)
{
   for (int i = 0; i < n; i++)
   {
      Image tempImg = Instantiate(lifeImg, 

                                  transform.position, 
                                  transform.rotation) as Image;
      tempImg.transform.parent = transform;
   }
   currentHealth += n;
}

public void ModifyLives(int amt)
{

   currentHealth += amt;
   Debug.Log(currentHealth);
}



After assigning the ‘
ModifyHealth’ function to the button parse it a value of '1'. For result see Figure 1.8.



Figure 1.8


Great the code works and our current health goes down. However, we want this to be represented visually and remove the ‘lifeImg’ objects like how we instantiate them. In fact, we want to remove the last one that was created. In order to do any of this we need to keep track of them some how. This requires a list which is similar to an array but more flexible and we will go into this in more detail in Part 7 as that is another topic for another day.


Great, part 6 is finished. We have laid down more foundations to the frame work.

We have learnt how to:

  • Manually created two new buttons, renamed and relabelled them
  • Assign a script and function to a button from another object 
  • Output values for the ‘Console’ using ‘Debug.Log()
  • Add ‘lifeImg’ game objects during run time via the buttons
  • Keep track of current health using a variable and modify it using the incremental operator
  • Decrease player health using the incremental operator with a negative value
  • Parse a function assigned to a button either a positive or negative value
  • Keep our code fairly reusable for later improvements to our code


In Part 7 we will learn how to use a list to keep track of our ‘lifeImg’ object created during runtime so we can update the latest one on the go making it appear empty. We will also make our code ready for half lives using different images and prevent our ‘currentHealth’ from going below zero or above a maximum value. Click here for Part 7.


If you liked this tutorial leave a comment below telling me why you like it and share it with a friend who will find it useful. If you didn’t like it, please leave a comment below saying why.

If you would would like to see more of these tutorials, please leave a comment below. And if you want more of this particular tutorial say what you want to see more of in the comments.


Download resources and project files.

Wednesday 19 October 2016

Zelda Style Life System Unity Tutorial – Part 5 of 10


Zelda Style Life System Unity Tutorial – Part 5 of 10


The end result of the full tutorial.

At the end of Part 5 we will have produced this (See image 1.0).
Image 1.0



Before you start you should know these things:

You should have gone through and completed ‘Part 4’ of this tutorial before going any further. If you find yourself not understanding some of the terminology or code of the tutorial I would also recommend going through the previous tutorial to get up to speed. I will leave a link to it below to go through at your leisure.

http://joseph-easter.blogspot.co.uk/2016/08/zelda-style-life-system-unity-tutorial_24.html

If you follow this tutorial and find I am moving too fast or if you don’t know the things in the list above, I would recommend getting up to speed and then come back to this tutorial when you are ready.


Links to Parts 1 - 10 of this tutorial series:

Part 1

Part 2

Part 3

Part 4

Part 6

Part 7

Part 8

Part 9

Part 10

With this tutorial if you want to convert this into JavaScript by all means do so but it may be easier for you to follow this in C# and stick with the language of the tutorial to make it easier.

PROJECT RESOURCES: At the bottom of the post there is a download link to a zip file. This files includes all files needed to follow Part 5 and the completed project file of Part 5.

In this part we will finish the foundation of the life system framework. After the this we will add more features to it and generally polish it so you can easily adapt it for your project. We will:

  • Control how many lives we have per row on screen
  • If lives per row is exceeded, put new life on a new row and reset it’s X position
  • Count how many lives the player currently has
  • Introduce a max lives variable so the current lives variable does not exceed this

Step 1:- Setting the Constraints

In most games when the player has multiple lives they can also gain lives. Quite often they can exceed the original number of lives they had in the first place through power ups. When they gain a new life there is normally a maxim number of them in a row. Then it resets and a new row is started below the first. This continues until either a portion of the screen is full or a predetermined value has been met.

With our script there are a few ways we can do this. If we didn’t have our ‘GridLayoutGroup’ component we could do it all through code using a series of for loops. Luckily we do and the ‘GridLayoutGroup’ component can do the heavy lifting for us. We will take a look at it now.



The particular variable we will be looking at is the ‘Constraintsenum, just under ‘Child Alignment’. This is the setting we will use in order to make sure the ‘lifeImg’ game objects only have a certain number of image objects per row.

It has three different settings, ‘Flexible’, ‘Fixed Column Count’, ‘Fixed Row Count’. (See figure 1.0)





Figure 1.0


First there is ‘Flexible’. With this setting, both the grid height and width will be flexible. We can keep it this way but we will have no control over the specific number of cells in each row and column. It will try to keep the number of cells in each the same though.

The ‘Fixed Column Count’ setting constrains the grid UI elements from exceeding a fixed number columns. When ‘Fixed Row Count’ is chosen, the grid elements will not exceed a certain number of rows. When ‘Fixed Column Count’ or ‘Fixed Row Count’ is chosen a variable appears under it called ‘Constraint Count’. This lists the maximum number of items in each row or column.

We can see this in action, if we set ‘Starting Health’ to ‘8’, set the constrains to ‘Fixed Column Count’ and keep ‘Constraint Count’ at ‘2’ the elements will be like in the image below. (See figure 1.1)





Figure 1.1: Spacing is set to 3 on both X and Y axis.




If we do the same thing but change ‘Fixed Column Count’ to ‘Fixed Row Count’ we will have a similar result to the image below. (See figure 1.2)




Figure 1.2




This is pretty handy, all we have to do it set a few variables and the component does the hard work for us. Using these settings we can set the values manually. However, we are creating this asset for the designer. We want to keep everything simple and all of our settings in one place rather having the designer looking all over the place in different scripts and components. We can do this by accessing these variables via our ‘LifeSystem’ script. We will go into dive into this in ‘Step 2’.



Step 2: - Setting the Row Count

In this step we will cover to how set the maximum number of lives per row and how to automatically set the constraint of the rows on the first frame.

The first thing we need to do is set the maximum number of lives per row and assign this to ‘Constraint Count’ of the ‘GridLayoutGroup’. We do this by creating a new public int at the top called ‘livesPerRow’. This is how many lives we want per row. For now I have set this to three just as an arbitrary number.

Next we need to access the constraint variable of the ‘gridLayoutGroup’. In our ‘ResetGridLayoutProperties’ method at the bottom of it we will access the constraint count and assign our ‘livesPerRow’ int to it.


Code:


public int livesPerRow = 3;

void ResetGridLayoutProperties()
{
  gridLayoutGroup = GetComponent<GridLayoutGroup>();
  gridLayoutGroup.cellSize = new Vector2(lifeImgWidth,
                                         lifeImgHeight);
  gridLayoutGroup.startAxis = GridLayoutGroup.Axis.Vertical;
  gridLayoutGroup.spacing = ImageSpacing();
  gridLayoutGroup.constraintCount = livesPerRow;
}



This is good but because we still have our ‘Constraint’ enem set to ‘Flexible’ we will not see a difference. We want to set this via in our function. You may ask ‘why don’t we just set it manually?’. Well the first reason has already been brought up in this tutorial. The other reason is that if some one messes with our project or changes the constraint by accident, the code will over ride it. Essentially we are making this idiot proof.

To do this we access the ‘constraint’ variable of our ‘gridLayoutGroup’ then set it to ‘GridLayoutGroup.Constraint.FixedColumnCount’ for the effect we want.

Code:


void ResetGridLayoutProperties()
{
  gridLayoutGroup = GetComponent<GridLayoutGroup>();
  gridLayoutGroup.cellSize = new Vector2(lifeImgWidth,
                                         lifeImgHeight);
  gridLayoutGroup.startAxis = GridLayoutGroup.Axis.Vertical;
  gridLayoutGroup.spacing = ImageSpacing();
  gridLayoutGroup.constraintCount = livesPerRow;
  gridLayoutGroup.constraint =
                        GridLayoutGroup.Constraint.FixedColumnCount;
}

Now if we run our code we will get this. (See figure 1.3)


Figure 1.3


How result of our code in ‘Play’ mode (left). Inspector settings changed via code (right).

We will change the number of lives per row later when we need to. This is pretty good so far, things are shaping up and we are getting there. What we need to do next is set the amount of health per heart.

Great, part five is finished. We have pretty much got the core of this done, the rest is just polish.

We have learnt how to:

  • Constrain UI grid elements to a fixed row or column 
  • Set the maximum number of elements in a row or column using ‘constrainCount
  • Set these variables via code to run automatically in the first frame of the scene

In Part 6 we will learn how to set our life system so we can easily add and take away health by clicking a few buttons. This way we can see the results of our work more quickly. In Part 7 we will cover how to set the amount of health per life, keep track of our of lives using a list (similar to an array) and change the image of the latest life image based on health current health. Click here for Part 6.


If you liked this tutorial leave a comment below telling me why you like it and share it with a friend who will find it useful. If you didn’t like it, please leave a comment below saying why.

If you would would like to see more of these tutorials, please leave a comment below. And if you want more of this particular tutorial say what you want to see more of in the comments.


Download resources and project files.