Unity 3D Health Pickups

We'll do some health packs now. When you're running low on health, you'll be able to walk up to a health pack, press the letter E on your keyboard and get an extra 20 points added to your health. The health pack will then disappear. Let's see how to do it.

This is all done with Triggers and a cube within a cube.

Add a new cube to your scene. (GameObject > 3D Object > Cube.) Call the new cube Health-Pack. You can place it anywhere you like, but we've placed ours just behind the soldier. Reduce the scale of the cube to these values:

X: 0.2
Y: 0.1
Z: 0.4

Here's our new cube in the Inspector:

Inspector showing the transform value of the pickup

The position of your health pack doesn't need to be the same as ours. But we had these:

Position

X: 14
Y: 0.125
Z: -18

Create a new material for your health pack. Change the Albedo to any colour you like. We went for green. Drag and drop your new material onto your new cube and it will look something like this in Scene view:

Scene view in Unity showing the health pack on the floor

Now duplicate this cube. Call the duplicate Health. In the Inspector, change the Scale to these values:

X: 0.8
Y: 0.8
Z: 0.8

Change the Y Position value to 0.5.

Now, in the Hierarchy, drag and drop Health-Pack onto Health:

Dragging and dropping in the Hierarchy

Health-Pack will then become a child of Health:

A parent and child in the Hierarchy

With Health selected in the Hierarchy, uncheck the Mesh Renderer in the Inspector. Also, check the box for Is Trigger for the Box Collider:

Unchecking the mesh renderer on the cube and setting a trigger

It should look like this in Scene view:

A cube in Scene view with the mesh renderer turned off

The outer green box with just the outline is the one the player will interact with.

Now we need some text on screen for when the player collides with the box. This will display what the player should do. (Press E to pick up health.)

Make sure nothing is selected in the Hierarchy (just click on a blank area). In the menu at the top of Unity, go to Game Object UI > Canvas. Right-click on your new canvas and select UI > Text - TextMesh Pro.

When you use TextMesh Pro for the first time, you may see a dialog box with the heading TMP Importer. Click the Import TMP Essentials button on this dialog box (you've seen it before in another tutorial). Once you do, Unity will import some stuff. When it's finished importing, the second button at the bottom will become available, Import TMP examples & Extras. Click this as well. Then click the X to get rid of the dialog box. Now have a look at your Project folder. You should see a new folder called TextMesh Pro.

But call your new TextMesh Pro object UseText. Your Hierarchy should look like this:

A canvas added to the Hierarchy

Now select the UseText item in the Hierarchy. Set the Text Input to this:

[E]
pick up

Set the Font Size to 32 and the Vertex Color to white. Then click the centre alignment button, as in the image below:

The text component being adjusted

If you switch to the Game tab at the top instead of Scene, it should look like this: (If it doesn't, just start your game. When you stop the game, you should see the text.)

Text on screen in Game view

In the Hierarchy, click on the Canvas and uncheck the box at the top to hide the text:

deactivating a canvas in the Inspector

With the box unchecked, the text should disappear from your Game view tab. We'll switch it back on when the player collides with our hidden box that's on top of the Health-pack item.

OK, we're all done here. We can now write the code.

 

Health Pack Code

In the Project area at the bottom of Unity, click onto your Scripts folder. Create a new C# script. Call it HealthPack. Double-click the script to open it up in your coding editor. You can delete the Start method because you don't need it.

Inside of the Class curly brackets, set up these variables:

public GameObject useText;
public static bool hasPickedUpHealthPack = false;
private bool hasEneteredTrigger = false;

The first variable is called usetText and is of type GameObject. This variable will hold our text from the screen. It's public because we need to drag our Canvas onto it.

The next variable is a bool called hasPickedUpHealthPack. Notice that it's a public static variable. We'll need to access this from the Player Health script soon. If it's true, we can increase the player's health.

The final variable is another bool. This one is called hasEneteredTrigger. This variable is false, initially. We'll set it to true when the player enters the trigger. If it's true, we can display the text in the Update method.

Now add these two methods to your code, just below the Update method but inside of the final curly bracket of the Class:

private void OnTriggerEnter(Collider other)
{

useText.SetActive(true);
hasEneteredTrigger = true;

}

private void OnTriggerExit(Collider other)
{

useText.SetActive(false);
hasPickedUpHealthPack = false;
hasEneteredTrigger = false;

}

So we have an OnTriggerEnter and OnTriggerExit method. Remember: the outer box is the trigger, and the script itself will be placed on this outer box. If the player enters the trigger, we have this code:

useText.SetActive(true);
hasEneteredTrigger = true;

The GameObject called useText sets SetActive to true. This will be the [E] pick up text. Next, we set hasEneteredTrigger to true.

When we exit the trigger, this code gets executed:

useText.SetActive(false);
hasPickedUpHealthPack = false;
hasEneteredTrigger = false;

We switch off the text and set our two Booleans to false.

The final code is for the Update method. Add this:

void Update()
{

if (hasEneteredTrigger) {

if (Input.GetKeyDown(KeyCode.E))
{

hasPickedUpHealthPack = true;
hasEneteredTrigger = false;
gameObject.SetActive(false);
useText.SetActive(false);

}

}

}

We first check to see if hasEneteredTrigger is true. If it is, then we have this if statement:

if (Input.GetKeyDown(KeyCode.E))
{
}

If you've set off the trigger, this if statement then checks if you're holding down the E key on your keyboard. If you are, then these lines of code get executed:

hasPickedUpHealthPack = true;
hasEneteredTrigger = false;
gameObject.SetActive(false);
useText.SetActive(false);

We first set the two Booleans to false. The next line is this:

gameObject.SetActive(false);

The gameObject is the outer cube, which is the parent of the inner cube. When you set the Active state of the outer cube to false, it will hide both the parent and the child. In other words, the health pack will disappear.

The final line switches off the text.

But your code should look like this:

Unity C# code for a health pickup

Save your work and return to Unity. Now drag and drop your HealthPack script onto the Health item (NOT Health-Pack item) in the Hierarchy:

Drag and drop the health pack script onto the Hierarchy

With the Health item still selected in the Hierarchy, drag your Canvas item from the Hierarchy onto the empty slot Use Text in the Inspector:

Drag and drop the canvas onto the Inspector

Let's give it a try. Play your game. Move to the health pack and you should see this on screen:

Game play for a health pickup

Press the E key on your keyboard and the health pack should disappear.

However, nothing will happen to your health score. It will stay where it is on 100. That's because we haven't written any code to increase the player's health. Let's do that now.

Go back to your PlayerHealth script. Add this new variable to the top of your code with all the others:

private int healthPackValue = 20;

This is an integer variable we've called healthPackValue. It's set to 20. You can change this, if you want. It's the amount that the health will increase by when a health pack is picked up.

Now add this Update method to your code:

private void Update()
{

if (HealthPack.hasPickedUpHealthPack)
{

playerHealth = playerHealth + healthPackValue;
HealthPack.hasPickedUpHealthPack = false;

if (playerHealth > maxHealth) {

playerHealth = maxHealth;

}

}

}

Your PlayerHealth code should then look like this:

Unity C# code to get the value of a health pickup

Now let's go through the new Update code to see what's happening.

We have this if statement wrapping everything:

if (HealthPack.hasPickedUpHealthPack)
{
}

In our HealthPack script, we added a public static Boolean variable called hasPickedUpHealthPack. The fact that it is public and static means it can be seen from other scripts. We're checking if it's true from the PlayerHealth script. If it's true, it means the player picked up a health pack by pressing the E key on the keyboard.

The next two lines in the if statement are these:

playerHealth = playerHealth + healthPackValue;
HealthPack.hasPickedUpHealthPack = false;

The first line adds the value of the health pack to the playerHealth variable. The second line sets hasPickedUpHealthPack back to false.

But we also need to check that the player's health hasn't gone above the maximum allowed, which we set to 100 in the maxHealth variable. If has gone above 100, we need to reset it. We do that with an if statement:

if (playerHealth > maxHealth)
{

playerHealth = maxHealth;

}

So, if the value in the playerHealth variable is greater than the value in the maxHealth variable, we have this:

playerHealth = maxHealth;

This assigns maxHealth (100) to whatever the player's health is, overwriting it,

Save your code and go back to Unity. Select the First person controller item in the Hierarchy so that you can see your Player Health value in the Inspector. Now play your game. Get shot a few times and then deal with the enemy. Once he's dead, pick up your health pack. You should see the Player Health value increase, as in the short video below: (34 seconds)

 

If you want, you can add a sound every time a health pack is picked up. As an exercise, try to do this for yourself. If you have problems, see below.

Here's a sound you can use:

Health Pickup Audio (106KB WAV file)

Download the file and then drag and drop it into your Audio folder in the Project area of Unity.

Right-click your SFX folder in the Hierarchy. Add a new empty object. Call it anything you like. In the Inspector for your new empty object, add a new Audio Source component. (Don't forget to uncheck Play on Awake.) Drag and drop the sound file you downloaded onto the Audio Clip item of the Audio Source component.

Go back to your HealthPack code. Add a new variable:

public AudioSource healthSound;

In the KeyCode part of your code, add a play line for the audio, highlighted in bold below:

if (Input.GetKeyDown(KeyCode.E))
{

healthSound.Play();

hasPickedUpHealthPack = true;
hasEneteredTrigger = false;
gameObject.SetActive(false);
useText.SetActive(false);

}

Save your work and go back to Unity. Click on one of your health pack items in the Hierarchy. You should see a new slot on your script in the Inspector, Health Sound. Drag your sound from the SFX list in the Hierarchy onto the slot.

Play your game again and pick up some health. If you're successful, you should hear the new sound play when a health pack is picked up.

You can add as many health packs as you like. Click on the Health item in the Hierarchy. Press CTRL + D on your keyboard to duplicate it. Move the duplicated item into the position you want.

 

Other kinds of pickups

The same idea as outlined above works with other types of pickup, such as ammo, for example. Put a cube over the ammo, switch off the Mesh Renderer and check the Is Trigger option in the Inspector. You then write code to display some USE text on screen, turn off the ammo, and then increase an ammo count variable.

Of course, it's no good just having the player's health score in the Inspector. We need to see it on screen. Let's do that now.

<--Back to the Unity 3D Course Contents Page