Skip to main content

First-Person Shooter: Health bar

info

This is Elympics First-Person Shooter tutorial: part 9. In this part we’ll be creating hp bar and death screen. See: Part 8.

Health bar

Your players need to fully understand what’s happening in the game, so the next step is to add several UI elements to it: the HP bar and the screen warning them about a possible death.

Let’s start with the HP bar. Add the Canvas component and the Event System to the scene and create a simple slider that will act as a bar with life points.

First-Person Shooter First-Person Shooter

To make your HP bar fully functional, you only need a script that will properly modify the "fill" value of the slider depending on the current state of health of the player.

To do this, create another new HealthBar.cs script:

public class HealthBar : MonoBehaviour
{
[SerializeField] private PlayersProvider playersProvider = null;
[SerializeField] private Slider healthSlider = null;

private void Start()
{
if (playersProvider.IsReady)
SubscribeToStatsController();
else
playersProvider.IsReadyChanged += SubscribeToStatsController;
}

private void SubscribeToStatsController()
{
var clientPlayerData = playersProvider.ClientPlayer;
clientPlayerData.GetComponent<StatsController>().HealthValueChanged += UpdateHealthView;
}

private void UpdateHealthView(float currentHealth, float maxHealth)
{
healthSlider.value = currentHealth / maxHealth;
}
}

This script will use the previously created PlayersProvider to get a reference to the player controlled by the client thanks to which you’ll be able to modify the slider depending on the value of that correct player's life points.

This class needs only references to the aforementioned PlayersProvider as well as to the Slider it will modify. The script itself doesn’t need to synchronize with the state on the server because for each client, it will display values for a different player.

As in the case of PlayersSpawner, in the Start method, you’ll need to make sure that PlayersProvider is properly initialized, and then, depending on the result, the SubscribeToStatsController method is executed. In this method, you obtain a reference to the player currently controlled by the client using PlayersProvier, and then, using GetComponent, you obtain a reference to the StatsController component.

While creating the StatsController class, you’ve already created a local event that is executed every time a player's hit points are modified. This event provides information about both the player's current health and its maximum possible level, thanks to which we can easily get a percentage of the current health. We assign the UpdateHealthView method to this event, the only task of which is to calculate the percentage of health (in the range of 0.0-1.0), and change the value of the "value" field in the slider responsible for displaying the current health status.

Now, just add the created script to the Slider in the scene and fill it with the required references:

First-Person Shooter

From now on, the HealthBar will track the health values of the player controlled by the client and display its value on the screen in the form of a slider.

Death screen

In order to fully understand the current situation in the game, you still have to create the death screen that will be displayed when the player is dead.

Start by creating an empty object on the Canvas that will be your death screen:

First-Person Shooter

To display the remaining amount of time until respawn on the death screen, add a TextField at the bottom of the screen. You’ll be showing the entire DeathScreen object by changing the alpha value in the CanvasGroup component.

First-Person Shooter

An object prepared in this way must also have an appropriate script that will control it, so you’ll need to create a new class DeathScreen.cs:

public class DeathScreen : MonoBehaviour
{
[SerializeField] private PlayersProvider playersProvider = null;
[SerializeField] private CanvasGroup canvasGroup = null;
[SerializeField] private TextMeshProUGUI deathTimerText = null;

private void Start()
{
if (playersProvider.IsReady)
SubscribeToDeathController();
else
playersProvider.IsReadyChanged += SubscribeToDeathController;
}

private void SubscribeToDeathController()
{
var clientPlayerDeathController = playersProvider.ClientPlayer.GetComponent<DeathController>();
clientPlayerDeathController.CurrentDeathTime.ValueChanged += UpdateDeathTimerView;
clientPlayerDeathController.IsDead.ValueChanged += UpdateDeathScreenView;
}

private void UpdateDeathScreenView(bool lastValue, bool newValue)
{
canvasGroup.alpha = newValue ? 1.0f : 0.0f;
}

private void UpdateDeathTimerView(float lastValue, float newValue)
{
deathTimerText.text = Mathf.Ceil(newValue).ToString();
}
}

Just like the previously created HealthBar.cs script, DeathScreen.cs also requires a reference to the PlayersProvider.cs class to be able to subscribe to the DeathController component of the player controlled by the client. In addition, we also need a reference to the CanvasGroup component to display the entire object each time the player is dead, and a reference to the textbox where we will display the remaining respawn time.

In the Start() method, the function initializing the entire script is called SubscribeToDeathController(). In this method, with the help of PlayersProvider, we get the player controlled by the client and then "pull" the DeathController component from it. This component provides the appropriate ElympicsVars and their ValueChanged events, thanks to which you’ll control the operation of the death screen:

  • Using the variable IsDead, you enable or disable the display of the entire object (UpdateDeathScreenView);
  • Using CurrentDeathTime, you receive information each time the respawn timer value changes. You display this information by rounding the float value using Ceil() - UpdateDeathTimerView.

The script prepared this way is already fully functional. The last step is to simply add it to the object of your death screen and complete the references:

First-Person Shooter

You are dead!

From now on, every time a player dies, they will see a screen informing them about their death and the time remaining until respawning.

First-Person Shooter

In the next part we'll be controling the gameplay by managing players' scores 💯