Wednesday 23 November 2016

Zelda Style Life System Unity Tutorial - Part 10 of 10

Zelda Style Life System Unity Tutorial - Part 10 of 10



The end result of the full tutorial.


At the end of Part 10 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 9’ 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 6

Part 7

Part 8

Part 9



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 10 and the completed project file of Part 10.

In this part we will work on polishing what we have by adding more detail and flexibility to the system.
We will: 

  • Make quarter health show when heart is nearly empty
  • Adjust a few parameters
  • See our finished code in action


Step 1: – Showing the Quarter Health Image

When we finished Part 9 we fixed most of the bugs, however we were left with one thing to sort out. Thanks to how the List for lifeImages works, when the player has a little bit of health left (a quarter or less), the system shows an empty heart image. This is not accurate and not what we want to happen, it happens thanks to a logical error (not something the compiler reports). We only want the empty heart to show when there is zero health in that heart.

This is quite a simple fix. The way we do this is by checking if the ‘lifeImagesIndex‘ is zero and ‘currentLifeHealth’ is greater than zero. Then we set the ‘lifeImagesIndex’ to one if the condition is met.

Code:

private void UpdateLives()
{
  bool restOfLivesAreEmpty = false;
  int i = 0;
  foreach (Image life in livesArray)
  {
    if (restOfLivesAreEmpty)
    {
      life.GetComponent<Image>().sprite = lifeImages[0];
    } else {
      i +=1;
      if (currentHealth >= i * healthPerLife)
      {
        life.GetComponent<Image>().sprite = 
                               lifeImages[lifeImages.Length - 1];
      } else {
        int currLifeHealth = (int)(healthPerLife – 
                                  (healthPerLife * i – 
                                   currHealth));
        int healthPerLifeImg = healthPerLife / lifeImages.Length;
        int lifeImagesIndex = currLifeHealth / healthPerLifeImg;
        if (lifeImagesIndex == 0 && currentLifeHealth > 0)
        {
          lifeImagesIndex = 1;
        }
        life.GetComponent<Image>().sprite = 

                                     lifeImages[lifeImagesIndex];
        restOfLivesAreEmpty = true;
      }
    }
  }
}



Now when we run the code we will get this. (See figure 1.0)



Figure 1.0.



Step 2: – Adjusting a few properties

Now you may have noticed that if we click the ‘Take Some Damage’ button, if we click it once the health decreases by one in the console but the heart graphic stays the same. If we click it two more times, then it shows a three quarter full heart instead of a full heart. This is just how the logic works. Each time we are only removing one health, and each heart image (e.g. full, quarter and so on) represent two health. In order for the heart image to change each time we ‘Take Some Damage’ we need to increase the amount of damage to at least three. (See Figure 1.1).



Figure 1.1


When we enter 'Play' mode and take some damage the sprite image used for 'lifeImg' now changes (Figure 1.2), and when there is still a little bit of life left our code fully works (figure 1.3).

Figure 1.2 left, figure 1.3 right.



Step 3: – Adding a few finishing touches

Great our Life system is nearly finished. All we need to do now is add a few finishing touches and we are done. In this step we will add a ‘Heal Me’ button. This is very simple, we will create another button and make it modify our health by adding six to ‘currentHealth’. Then you can use this in your game.

The first thing to do is create a new button from the ‘Create’ menu and give the the same width and height as the first two buttons (or you can duplicate the ‘Take Some Damage’ button). Then position it beside the ‘Take Some Damage’ button (to the right of it), name rename the button to ‘Heal 6 Damage Btn’ and change the ‘Text’ label to say ‘Heal Me’. (For an example see figure 1.4 below)




Figure 1.4.
Here the ‘Heal Me’ button is positioned at X: 163.1, Y: 47 and Z: 0.



After this go down to the button script, there should be an ‘enum’ dropdown menu that reads ‘LifeSystem.ModifyHealth’. Under this there should be an ‘int’ field. In here enter ‘6’ with out an ‘-‘ (see figure 1.5). This will add health to the player when they make some damage but will not go any higher than the ‘maxLives’ variable.



Figure 1.5.





Interactive Demo – End Result


[insert link to web player]

Great, Part 10 is finished.

We have learnt how to:


  • Fix the logical error (show a quarter heart instead of empty heart when there’s a little health left)
  • Tweak ‘Take Damage’ parse value to show health depleting correctly
  • How to heal the player using ‘Modify Health’ and not exceed the ‘maxLives’ variable


Great, you have completed the whole tutorial. Thanks for taking the time to follow the entire way through. We have learnt a lot along the way. 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 16 November 2016

Zelda Style Life System Unity Tutorial - Part 9 of 10

Zelda Style Life System Unity Tutorial - Part 9 of 10




The end result of the full tutorial.


At the end of Part 9 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 8’ 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.



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 6

Part 7

Part 8

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 9 and the completed project file of Part 9.

In this part we will work on polishing what we have by adding more detail and flexibility to the system.

We will:

  • Fix all the errors created in Part 8

Step 1: – Fixing the 'Divide By Zero' Error

At the moment a few things will happen when we try our code during runtime. When we click the ‘Take Some Damage’ button a few times we get an error ‘Divide By Zero Exception’ (See figure 1.0). This is down to a few things. In the inspector we need to change ‘startingHealth’ to 30, then change ‘healthPerLife’ to 10. Then in the Start function where we have a reference to ‘AddLives’ we parse it ‘startingHealth’ we need to tells it to divide that by ‘healthPerLife’. (See figure 1.0)


Figure 1.0


Code:

void Start ()
{
  GetScreenDimentions();
  SetImageSize();
  ResetGridLayoutProperties();
  AddLives (startingHealth / healthPerLife);
}


After this we need to change some of the code in the ‘ModifyHealth’ function and clamp the ‘currentHealth’ variable (this is causing part of the problem). We need to make sure ‘currentHealth’ does not rise above a set maximum nor go below zero. Unity has a function for this called ‘Mathf.Clamp’, you set the variable you want to the function, then parse it the variable you want clamped, the minimum and the maximum. Then it takes care of the rest for you. The minimum we will set it to is zero and the maximum we will set it to is a new private variable called ‘maxLives’.

Code:

private int maxLives;

void ModifyHealth (int amt)
{
  currentHealth += amt;
  currentHealth = Mathf.Clamp(currentHealth, 0, maxLives);
  UpdateLives();
}


Step 2: – Fixing the 'currentHealth' value in 'AddLives' with 'maxHealth'

Now there is another bit causing the problem. In ‘AddLives’ ‘currentHealth’ is incrementally added to by ‘n’. This worked ok when we just have one icon her health, but since we now have multiple health values per icon it’s causing us problems. First off we want to increase ‘MaxLives’ when we gain more lives when our health if full. Then we want out ‘currentHealth’ to be the same as ‘maxLives’. In order to get max lives to increase based on health, we need to multiply ‘n’ (parsed to it by the ‘AddHealth’ function, and multiply it by ‘healthPerLife’.


Code:

void AddLives(){
  for (int i = 0; i < n; i++)
  {
    Image tempImg = Instantiate(lifeImg,
                                transform.position,
                                transform.rotation;
    tempImg.transform.parent = transform;
    livesArray.Add(tempImg);
  }

  maxLives += n * healthPerLife;
  currentHealth = maxLives;
  UpdateLives();
}



Now we have this as a quick summary of what the ‘lifeImagesIndex’ does is, if each ‘lifeImg’ is equal to e.g. ten, and we have ten images in our ‘lifeImagesArr’ then each image is equivalent to one health. Next we will use ‘lifeImagesIndex’ to reference the ‘lifeImagesArr’ element we need in the ‘Sprite’ array and assign it to ‘lifeImg’.

Code:

private void UpdateLives()
{
  bool restOfLivesAreEmpty = false;
  int i = 1;
  foreach (Image life in livesArray)
  {
    if (restOfLivesAreEmpty)
    {
      life.GetComponent<Image>().sprite = lifeImages[0];
    } else {
      if (currentHealth >= i * healthPerLife)
      {
        life.GetComponent<Image>().sprite =
                            lifeImages[lifeImages.Length - 1];
      } else {
        int currLifeHealth = (int)(healthPerLife –
                                  (healthPerLife * i –
                                   currentHealth));
        int healthPerLifeImg = healthPerLife / lifeImages.Length;
        int lifeImagesIndex = currLifeHealth / healthPerLifeImg;
        life.GetComponent<Image>().sprite =
                            lifeImages[lifeImagesIndex];
        restOfLivesAreEmpty = true;
      }
    }
  }
}


Step 3: – Fixing the 'foreach' iterator logical error

If we leave things as they are we can see the result of our bug fixes, but there are more to go. If we were to run our code, and taking some damage, the ‘currentHealth’ variable would drop (visible in the console), but the hearts would not deplete (until we get to zero where the middle one becomes empty). This is still not good enough. (See figures 1.1 and 1.2).



Figure 1.1 left, figure 1.2 right.


Fixing this nasty bug is very simple in ‘UpdateLives’ where we declare ‘i = 1’, we need to change this to zero ‘0’. Then at the top of the first else statement we need to increment ‘i’ by 1 to properly keep track of the latest element.
Code:

private void UpdateLives()
{
  bool restOfLivesAreEmpty = false;
  int i = 0;
  foreach (Image life in livesArray)
  {
    if (restOfLivesAreEmpty)
    {
      life.GetComponent<Image>().sprite = lifeImages[0];
    } else {
      i += 1;
      if (currentHealth >= i * healthPerLife)
      {
        life.GetComponent<Image>().sprite = 

                                  lifeImages[lifeImages.Length - 1];
      } else {
        int currLifeHealth = (int)(healthPerLife – 

                                  (healthPerLife * i – 
                                   currentHealth));
        int healthPerLifeImg = healthPerLife / lifeImages.Length;
        int lifeImagesIndex = currLifeHealth / healthPerLifeImg;
        life.GetComponent<Image>().sprite = 

                                  lifeImages[lifeImagesIndex];
        restOfLivesAreEmpty = true;
      }
    }
  }
}



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

We have learnt how to fix:


  • A divide by zero error using ‘Mathf.Clamp’ with our ‘currentHealth
  • Add health at the start properly by dividing ‘startingHealth’ by ‘healthPerLife
  • Increate max lives by new lives added time by health per life
  • Modify an iterator


In Part 10 we will learn how to show a quarter heart when a heart is nearly empty, adjust a few parameters, heal the player and finally see our code in action. Click here for Part 10.


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 9 November 2016

Zelda Style Life System Unity Tutorial - Part 8 of 10

Zelda Style Life System Unity Tutorial - Part 8 of 10


The end result of the full tutorial.


At the end of Part 8 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 7’ 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/11/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 6

Part 7

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 8 and the completed project file of Part 8.

A quick note: This week’s tutorial is longer than normal, about twice as long. This is because the content covered (the calculations) are quite complex. I would have divided this into two separate parts to keep it short but it would have been messy.

In this part we will work on polishing what we have by adding more detail and flexibility to the system.
We will learn how to:

  • Learn what a ‘foreach’ loop is and how to use one
  • Check how full a life is & manipulate how much each ‘lifeImg’ can hold
  • Set an image’s sprite to an element in an array (regardless of it’s size)
  • Keep track of each ‘lifeImg’ and index the lifeImages array
  • Assign a partial heart image to ‘lifeImg’ based on


Step 1: – Updating Lives Icon Part 1 - Sorting through Full and Empty Lives


We will change things up a bit, in your game you may want to have multiple health values her health icon, which some games do. You may have multiple images to show half or a quarter of a heart. In order to do this, we need a way of updating the image texture of the last ‘lifeImg’ on the HUD to reflect how full it is in correspondence to the ‘
currentHealth’ variable.

In the ‘
ModifyHealth’ function we will add a reference to a new function ‘UpdateLives’. Then we will create this new private function below ‘ModifyHealth’. In other words, we want this function called every time the player’s health is modified. We will also add a reference to it in ‘AddLives’ in case you want to update the icon when you add a new ‘lifeImg’.


Code:

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

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


void ModifyHealth (int amt)
{
  currentHealth += amt;
  Debug.Log(currentHealth);
  UpdateLives();
}

private void UpdateLives ()
{


}



In this function we need to see how many ‘lifeImg’ Image’s we have in the list; we could just use ‘
Count’ but we need to change the image texture of the last element in the list as well. For this we will use a ‘foreach’ loop. This will run through the list at least once and continue as long as it can find what it is looking for. In our case we are telling it to look for an object of type ‘Image’ in the ‘livesArray’. Then it will make the temporary ‘Image’ variable ‘life’ equal the current element in ‘livesArray’.

As we are using this to keep track of how many ‘
Image’ elements are in the ‘livesArray’ we will also need a temporary variable to store this number. We will use an ‘int’ called ‘i’ and use this to reference the current element in the ‘List’.

In this ‘foreach’ loop we will need to check for a few things on each heart. If the ‘lifeImg’ is full assign it the life full image (we will import these in the next step). We do checking if ‘currentHealth’ is greater than or equal to ‘i’ multiplied by a new variable ‘int’ called ‘healthPerLife’. This means e.g. if ‘i’ is set to ‘5’ and if ‘healthPerLife’ is set to ‘10’, the total will equal ‘50’ and and if ‘currentHealth’ is the same or equal to, then this particular heart will be completely full.

Next we will assign the ‘livesArray’ element the full life texture. We do this by creating a new array called ‘lifeImages’ of type ‘Sprite’ and set the ‘Length’ to five. Then we assign the last element of the array (the ‘Length’ of the array minus 1) to the ‘sprite’ variable of the ‘Image’ script of the current ‘livesArray’ element we are referencing. This depends on how you have set up your array, with mine the full image is the last one in the array.


Code:

public int healthPerLife = 4;

public Sprite [] lifeImages = new Sprite[5];

private void UpdateLives ()
{
  int i = 1;
  foreach (Image life in livesArray)
  {
    if (currentHealth >= i * healthPerLife)
    {
      life.GetComponent<Image>().sprite = 

                                  lifeImages[lifeImages.Length - 1];
    }
  }
}



Then we need a condition for if the current life is empty, if it is then the rest of the lives must also be empty and we need a flag for that. After the if statement, we need a way of saying if the condition has not been met then we need to say that the rest of the lives are also empty. We will create a new temporary Boolean called ‘restOfLivesAreEmpty’ and in the else statement flag it as true.


Code:

public int healthPerLife = 4;

public Sprite [] lifeImages = new Sprite[5];

private void UpdateLives ()
{
  bool restOfLivesAreEmpty = false;
  int i = 1;
  foreach (Image life in livesArray)
  {
    if (currentHealth >= i * healthPerLife)
    {
      life.GetComponent<Image>().sprite = 

                                  lifeImages[lifeImages.Length - 1];
    } else {
      restOfLivesAreEmpty = true;
    }
  }
}



Once ‘restOfLivesAreEmpty’ has been set to true there is no point in checking all the lives one by one because we know they are empty. Once we know the rest are empty we need a way to automatically set the rest to the empty sprite. This is quite easy to do. In our function we need to create another if statement that checks if ‘restOfLivesAreEmpty’ is true, then set each ‘liveImg’ to the empty. Then we finish it with and ‘else’ statement and put our last if statement in it telling it what to do if rest of the lives are full.


Code:


public int healthPerLife = 4;

public Sprite [] lifeImages = new Sprite[5];

private void UpdateLives ()
{
  bool restOfLivesAreEmpty = false;
  int i = 1;
  foreach (Image life in livesArray)
  {
    if (restOfLivesAreEmpty)
    {
      life.GetComponent<Image>().sprite = lifeImages[0];
    } else {
      if (currentHealth >= i * healthPerLife)
      {
        life.GetComponent<Image>().sprite = 

                              lifeImages[lifeImages.Length - 1];
      } else {
        restOfLivesAreEmpty = true;
      }
    }
  }
}



Step 2: – Updating Lives Icon Part 2 - Adding Multiple Health Values Per Health Icon

Now we can sort which lives are full and empty and set them to the appropriate image. The next step is sorting which lives are partially full and assign the corresponding image to them. We need to get the players health and make it correspond to the number of images in the ‘
liveImages’ array show show how much health of left in said ‘lifeimg’.

In the '
else' statement where we set ‘restOfLivesAreEmpty’, we need to work out how much health each ‘lifeImg’ has. We get how much health the current ‘lifeImg’ has by creating an ‘int’ called ‘currLifeHealth’, then we get ‘healthPerLife’ (cast as an int) and put this into brackets (it’s part of a larger equation). Then we take away ‘healthPerLife’ and multiply it by ‘i’ then minus ‘currentLives’ from that. After this we put that part of the equation in brackets to get the value we need.

Code:

public int healthPerLife = 4;

public Sprite [] lifeImages = new Sprite[5];

private void UpdateLives ()
{
  bool restOfLivesAreEmpty = false;
  int i = 1;
  foreach (Image life in livesArray)
  {
    if (restOfLivesAreEmpty)
    {
      life.GetComponent<Image>().sprite = lifeImages[0];
    } else {
      if (currentHealth >= i * healthPerLife)
      {
        life.GetComponent<Image>().sprite = 

                               lifeImages[lifeImages.Length - 1];
      } else {
        int currLifeHealth = (int)(healthPerLife - 

                                  (healthPerLife * i - 
                                   currentHealth));
        restOfLivesAreEmpty = true;
      }
    }
  }
}



To explain how this works, imagine the player has a maximum health of forty and their current health is thirty-eight. In the second lot of brackets which has the equation ‘
healthPerLife * i – currHealth’. If the loop is in it’s fourth round, ‘healthPerLife * i’ would equal forty and then we minus our current health using ‘currHealth’ (which is thirty-eight) which equals a total of two. With ‘healthPerLife’ in the first set of brackets this is equal to ten, which we subtract two (from the next set of brackets in the equation we just looked at). This equals a total of eight, which is how much health this current ‘lifeImg’ will have.

Next up we need to work out how much health each image represents. This is quite easy but will change depending on how many images you decide to have in your game. We will create another ‘int’ below ‘currHealth’ called ‘healthPerLifeImg’. We will work this out by assigning ‘healthPerLifeImg’ the equation ‘healthPerLife’ divided by ‘lifeImages.Length’.


Code:


public int healthPerLife = 4;


public Sprite [] lifeImages = new Sprite[5];

private void UpdateLives ()
{
  bool restOfLivesAreEmpty = false;
  int i = 1;
  foreach (Image life in livesArray)
  {
    if (restOfLivesAreEmpty)
    {
      life.GetComponent<Image>().sprite = lifeImages[0];
    } else {
      if (currentHealth >= i * healthPerLife)
      {
        life.GetComponent<Image>().sprite = 

                               lifeImages[lifeImages.Length - 1];
      } else {
        int currLifeHealth = (int)(healthPerLife - 

                                  (healthPerLife i - 
                                   currentHealth));
        int healthPerLifeImg = healthPerLife / lifeImages.Length;
        restOfLivesAreEmpty = true;
      }
    }
  }
}



In the next step we will assign correct partially full sprite to the ‘lifeImg’ UI element.



Step 3: – Updating Lives Icon Part 3 - Assigning Partial Health Image to the Icon

In this step we will assign the ‘lifeImg’ one the the sprites in the ‘lifeImage’ array according to how full it is. In order to do this though we need a way to index which image to assign the ‘lifeImg’ UI element. Under the ‘healthPerLifeImg’ variable we will create another ‘int’ called ‘lifeImagesIndex’. Now to get the index value to want, we have to make ‘lifeImagesIndex’ equal ‘currLifeHealth’ divided by ‘healthPerLifeImg’.


Code:

public int healthPerLife = 4;

public Sprite [] lifeImages = new Sprite[5];

private void UpdateLives ()
{
  bool restOfLivesAreEmpty = false;
  int i = 1;
  foreach (Image life in livesArray)
  {
    if (restOfLivesAreEmpty)
    {
      life.GetComponent<Image>().sprite = lifeImages[0];
    } else {
      if (currentHealth >= i * healthPerLife)
      {
        life.GetComponent<Image>().sprite = 

                               lifeImages[lifeImages.Length - 1];
      } else {
        int currLifeHealth = (int)(healthPerLife - 

                                  (healthPerLife * i -
                                   currentHealth));
        int healthPerLifeImg = healthPerLife / lifeImages.Length;
        int lifeImagesIndex = currLifeHealth / healthPerLifeImg;
        restOfLivesAreEmpty = true;
      }
    }
  }
}



Now we have this as a quick summary of what the ‘
lifeImagesIndex’ does is, if each ‘lifeImg’ is equal to e.g. ten, and we have ten images in our ‘lifeImagesArr’ then each image is equivalent to one health. Next we will use ‘lifeImagesIndex’ to reference the ‘lifeImagesArr’ element we need in the ‘Sprite’ array and assign it to ‘lifeImg’.


Code:

public int healthPerLife = 4;

public Sprite [] lifeImages = new Sprite[5];

private void UpdateLives ()
{
  bool restOfLivesAreEmpty = false;
  int i = 1;
  foreach (Image life in livesArray)
  {
    if (restOfLivesAreEmpty)
    {
       life.GetComponent<Image>().sprite = lifeImages[0];
    } else {
       if (currentHealth >= i * healthPerLife)
      {
         life.GetComponent<Image>().sprite = 

                          lifeImages[lifeImages.Length - 1];
      } else {
         int currLifeHealth = (int)(healthPerLife - 

                                   (healthPerLife * i - 
                                    currentHealth));
         int healthPerLifeImg = healthPerLife / 
                                          lifeImages.Length;
         int lifeImagesIndex = currLifeHealth / 
                                          healthPerLifeImg;
         life.GetComponent<Image>().sprite = 

                                lifeImages[lifeImagesIndex];
         restOfLivesAreEmpty = true;
      }
    }
  }
}



Just to recap, ‘lifeImagesIndex’ works by getting currentLifeHealth’ divided by ‘healthPerLifeImg’ which in our case, we have ten health per life image with an array of five sprite images (including empty). This means that each sprite in the array equals two health each, therefore if ‘lifeImagesIndex’ equals three, then it will assign the third sprite in the ‘lifeImages’ array (number three in the array including element zero).

Since we have done a lot of code, I will change things up a little. We are referencing our ‘lifeImages’ array of ‘Sprites’, but we have not added any images to our array yet. If we run our code we will get a ‘null’ error when we modify our health. In the next step we will import the art package and add the images to the array.


Step 4: – Updating Lives Icon Part 4 - Importing and Adding the Art Assets

In the folder ‘Resources’ go to ‘Heart Icons’, then ‘Heart Icons Vertical Fill’ (there is also another folder for horizontal fill, but we won’t use those here, you can use them in your game if you like). Drag this folder into the ‘Assets’ project folder in Unity and import everything (if you have not already imported it). (See figure 1.1)



Figure 1.1


Then, select ‘LifeSystemManager’ and in the ‘Inspector’ penal go to the ‘Life Images’ array and expand it. Drag the images as you see here in figure 1.2. (See figure 1.2)




Figure 1.2

After this drag the ‘Heart Icon Full’ into the sprite variable of the ‘lifeImg’ prefab. (See figure 1.3).



Figure 1.3

Great, part eight is finished there is still more to do but it is certainly getting there (with regards to errors).


We have learnt how to:


  • Use a ‘foreach’ loop, check player’s health according to health per life
  • Set a life icon to a full or empty sprite
  • Index a sprite array according to player health and health per life
  • Set ‘lifeImg’ to an element in sprite array using an index to show partial health
  • Make each partial health sprite in array represent some health
  • Import Art Assets

In Part 9 we will cover how to fix all the errors in our script. Then in part 10 we will cover a few logical errors. Things such as when a life has a little health left (about a quarter) how to stop it from showing as empty and set it to the quarter full image and show it fully working. Click here for Part 9.

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.