Jump to content
  • entries
    44
  • comments
    19
  • views
    2315

Day 19 Creating Player Health System and Health UI in Unity

Josh Chang

599 views

In the current state of our game, we can defeat the enemy, however we can never lose.

Today in Day 19, we’re going to start working on the code to fix this.

The first step is that we’re going to create health and a health bar for our player so that we can receive damage and know when we’re going to lose.

Without any delays, let’s get started!

Creating the Health Bar UI

The first thing we should do when creating a health system is to create the UI for our health.

Just like any UI elements, we’ll be using Unity’s UI system to create a health bar, specifically, we’re going to use Unity’s Slider.

We already have an existing UI canvas called: HUD, right click it and select UI -> Slider to create a new Slider. If we don’t have a UI Canvas already, Unity would have automatically created it for us.

We’re going to rename our Slider to Health Bar.

Now you’ll have something like this if we go to 2D mode in our Scene tab with our hierarchy.

 
0*fei7jVmkL8f8fR75.png

We’re going to need to make some adjustments to our slider to make it look nicer.

First off, we don’t need the slider bar. Delete Handle Slider Area.

Next select Health Bar and in the Slider (Script) component range set theMax Value to be 100. Notice a little problem here?

 
0*zF0IagGICqB7iSjd.png

Our value is 0, but our bar is still there. Also, if we were to move our value to 100, the whole bar wouldn’t be filled either.

I found a great answer regarding how to make a slider empty.

To make the adjustments that we want, we have to:

  1. Set Width of Fill to be 0
  2. Go to Fill Area and drag the bar until it fits into the background. In my case, my ending values are Pos X: 75, Width: 160, and the rest is left to its default value.

Here’s what it looks like now:

 
0*RiLqeCcUgitgLjpN.png

However now we have another problem, if we were to set the value of the slider to 1, here’s what we would get:

 
0*wmuKKmFED0fJwEN1.png

Notice how our fill bar is on the right side of the actual bar itself.

Unfortunately, there doesn’t seem to be an answer that resolved the problem for me. This might be more of a Unity problem than anything else.

However, that doesn’t mean we’ll just give up.

We can simply fix it the same way you might never have noticed it in the Survival Shooter tutorial: we’ll expand the background of the slider so that the bar would naturally look like it’s correct.

To do that, we go to Background and then change Left, Top, Right, and Bottom to -3

After that we should have something like this:

 
0*uxVI6MWDq8uDN8J4.png

Much better, right? Nothing looks out of place!

Now that we have the health bar looking nicer, it’s time to move it to the bottom left corner. Selecting Health Bar, go to the Rect Transformcomponent, click on the square, to open up the UI alignments and hit Shift+Ctrl and left click the bottom left option to move everything to the bottom left corner.

Right now, everything is exactly at the bottom left corner and doesn’t look nice. Let’s add some adding.

Click Health Bar and set Pox X to be 15 and Pos Y to be 10.

When you’re done, your game should look like this now (don’t forget to set your slider value to be 100)!

 
0*ZuQH1nqVYe8aFYIC.png

Creating our Player Health System

Creating the Player’s health

Now that we have an UI health bar, it’s time to write some code to create the player’s health.

First, click on our Player game object and create a new script called PlayerHealth. This script will control the player health whenever they get damaged and then show these changes in our health bar.

Here’s what our PlayerHealth script looks like:

 
using UnityEngine;
using UnityEngine.UI;
public class PlayerHealth : MonoBehaviour
{
    public Slider HealthBar;
    public float Health = 100;
    private float _currentHealth;
    void Start ()
    {
        _currentHealth = Health;
    }
    public void TakeDamage(float damage)
    {
        _currentHealth -= damage;
        HealthBar.value = _currentHealth;
    }
}
 

Here’s how our script works:

  1. We create a public Slider that will be our HealthBar. It’s important to note that we need to import UI otherwise the compiler would complain to us about our Slider object.
  2. Next, we create a public Health to represent our max health and _currentHealth to represent how much health our player has.
  3. In Start() we instantiate our _currentHealth to be our max health.
  4. Finally, we create public TakeDamage(), public meaning that another script can use this component and call the function. Inside this function, we get our damage amount and we update our _currentHealth and we change the value of our slider to reflect health loss.

Before we proceed on, make sure to drag our HealthBar game object to our PlayerHealth script component.

Like so:

 
0*GYcg8xaj10BA3z1V.png

Writing the Damage Dealing Code

Now that we have that setup, the next thing we need to do is create the code that calls TakeDamage().

Luckily for us, we already have a script that deals with most of this: EnemyAttack.

All we need to do is grab an instance of our new PlayerHealth script and then run the take damage code.

 
using UnityEngine;
using System.Collections;

public class EnemyAttack : MonoBehaviour
{
    private Animator _animator;
    private GameObject _player;
    private bool _collidedWithPlayer;
    void Awake()
    {
        _player = GameObject.FindGameObjectWithTag("Player");
        _animator = GetComponent<Animator>();
    }
    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject == _player)
        {
            _animator.SetBool("IsNearPlayer", true);
        }
        print("enter trigger with _player");
    }
    void OnCollisionEnter(Collision other)
    {
        if (other.gameObject == _player)
        {
            _collidedWithPlayer = true;
        }
        print("enter collided with _player");
    }
    void OnCollisionExit(Collision other)
    {
        if (other.gameObject == _player)
        {
            _collidedWithPlayer = false;
        }
        print("exit collided with _player");
    }
    void OnTriggerExit(Collider other)
    {
        if (other.gameObject == _player)
        {
            _animator.SetBool("IsNearPlayer", false);
        }
        print("exit trigger with _player");
    }
    private void Attack()
    {
        if (_collidedWithPlayer)
        {
            _player.GetComponent<PlayerHealth>().TakeDamage(10);
        }
    }
}

 

In our script, we already have access to the player and detection for when we attack, so all we need to do is grab our PlayerHealth script and trigger our TakeDamage function when we call Attack() in EnemyAttack.

As you might recall from previous tutorials, the way that this code works is that:

  1. We have a trigger collider that detects when our knight should start attacking
  2. Then we have a mesh collider on our player that will detect when we’re touching the player
  3. Finally, in our animation, we set a point in time to call Attack() and when that happens, if the knight is still in contact with our player, we’ll take damage.

With this, we have everything we need to have a complete game, or you might think

If you were to play the game right now, you would have encountered a new problem that hasn’t been realized until now:

If we were to play the game while looking at our console. Whenever we bump into the knight, we would hit OnColliderEnter() get hit, and then for some reason run OnColliderExit() even if we don’t move the player.

As a result, if the player never moves, they’ll only get damaged once. How’s that for being boring?

We’ll solve this tomorrow, because it’s getting late today.

Conclusion

Today in day 19, we created a health system that allows our player to receive damage from our already existing enemy attack code.

We’re almost done, but we’ve encountered a problem where the enemy stops damaging us even when it looks like they successfully attacked us.

I have an idea of what the problem is, but we’ll talk more about that tomorrow!

Source: Day 19

Visit the 100 Days of Unity VR Development main page.

Visit our Homepage



0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By OConquestGame
      Hello there!
      I’m the creator and producer of an upcoming visual novel / video game. 
      My team and I are looking for artists (character and background), writers (experienced in writing relatable characters and witty dialogue), and programmers (familiar with unity and creating mini games). 
      Our team is a group of close friends looking to break the mold of the traditional visual novel and create something new and positive. This game will be highly promoted and be a great portfolio piece. Rates are negotiable!
      If you are interested please contact/message us today! OConQuestGame@gmail.com
    • By Kamal Wafi
      Hi there,
      i recently start learning unity and im working in my first game ,
       
      I was wondering if unity had functions to support the motion control effect (tilting screen to move character) you see
      in doodle jump (which is 2d game) ? If it exists, what are they called? and how it works ?

      Thanks
    • By 3dmodelerguy
      For reference I am use Unity as my game engine and the A* Pathfinding Project for path finding as there is no chance I would be able to create anything close to as performant as that in any reasonable amount of time.
      So I am looking to build a game that is going to have a very similar style as Prison Architect / Rim World / SimAirport / etc. One of the things that I assume is going to effect performance is path finding. Decisions about the game I have already made that I think relate to this are:
      1. While I am going to be using Colliders, all of them will be trigger colliders so everything can pass through each other and I will not be use physics for anything else as it has no relevance for my game
      2. I am going to want to have a soft cap at the map size being 300x300 (90,000 tiles), I might allow bigger sizes but do something like Rim World does in warning the player about possible side effect (whether it be performance or gameplay)
      3. The map will be somewhat dynamic in that the user will be able to build / gather stuff from the map but outside of that, it should not change very much
      Now I am going to build my game around the idea that users would be in control of no more than 50 pawns at any given time (which is something I can probably enforce through the game play) but I am also going to want to have number other pawns that are AI controlled on the map (NPCs, animals, etc.) that would also need path finding enabled. Now I did a basic test in which I have X number of pawns pick a random location in the 300 x 300 map. move towards it, and then change the location every 3-5 seconds. My initial test was pretty slow (not surprising as I was calculating the path every frame for each pawn) so I decided to cache the calculated path results and only update it ever 2 seconds which got me:
      100 pawns: 250 - 450 FPS
      150 pawns: 160 - 300 FPS
      200 pawns: 90 - 150 FPS
      250 pawns: 50 - 100 FPS
      There is very little extra happening in the game outside of rendering the tilemap.
      I would imagine the most pawns on the map at a given time that need path finding might be a 1000 (and I would probably be able to make due with like 500 - 600). Now obviously I would not need all the pawn to be calculation paths every 2 seconds nor would they need to be calculating paths that are so long but even at a 5 second path refresh rate and paths that are up to 10 tiles long, I am still only able to get to about 400 pawns before I start to see some big performance issues. The issue with reducing the refresh rate is that there are going to be cases where maybe a wall is built before the pawns path is refreshed having them walk through the wall but not sure if there is a clean way to update the path only when needed.
      I am sure when I don't run the game in the Unity editor I will see increase performance but I am just trying to figure out what things I could be doing to make sure path finding is as smaller of a performance hit as possible as there is a lot of other simulation stuff I am going to want to run on top of the path finding.
    • By Gas Lantern Games
      Hello!

      I have spent the last year and a half developing a game in my spare time in Unity! I am releasing it soon on Steam. Ant Empire is a strategic remake of some older games. It is influenced by games such as Ant Empire and Civilization.

      I am currently doing a kickstarter to help fund an AI before launch.

      I have attached some images (tried some gifs but they were too large) to show the current stage of Ant Empire, which is nearly completed.







    • By Alex Yarotsky
      Making games is hard. You need all kinds of technical and creative skills, you need a big team, a budget...
      But making your first game can be even more difficult if you have no previous experience in game development and your team is only two people.
      But it didn't stop us. We quit our jobs and started this indie game journey full of mistakes and pitfalls.
      Why? What encouraged us to make this stupid move?
      Inspired by Extra Credits, Hellblade Dev Diaries, and ThinMatrix we decided to start a weekly behind the scenes show. There we'll be showing bits of our production process. The whole project is a huge and risky experiment for us and we would love to hear your support and recommendations.
      We are opened to all sorts of feedback. Even if you consider something is of a low quality in our video, please let us know it as is. We would love to learn from the community and improve.
      Thank you.
       
       
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!