Implementing the Health System

Renato Figueiredo
4 min readDec 14, 2023

Objective: Learn how to implement a Health System for the player.

Our game works wonder at the moment, but when our player gets hit, there is no way for him to get more lives. How about implementing a system that allows our player to gain back some lives ? And of course, we can limit the amount he can have anyways.

As usual, we can start by creating our GameObject, animate it and give it the proper components.

Creating our Life Powerup object.

So now we are going to divide our Powerup types. Before we had all of them within our SpawnManager GameObject array. Why are we going to separate them ? Well, for starters, we need ammo to drop more frequently than in the current state. Also, we’d like to have our Life Powerup to only drop when our player has already lost a life.

[SerializeField] private GameObject[] _powerups, _utilitiesPowerups;
Updating our SpawnManager arrays.

Now that we have two different array for the type of powerups, lets see how to code our changes.

private Player _player;
private void Start()
{
_player = GameObject.Find("Player").GetComponent<Player>();
if (_player == null)
Debug.LogError("Player is NULL on the Spawn Manager.");
}
private IEnumerator SpawnUtilityPowerUpRoutine()
{
while (!_isPlayerAlive)
{
float randomPositionX = Random.Range(-9.2f, 9.2f);
_utilityPowerUpSpawnPosition.Set(randomPositionX, 7.35f, 0f);
if(_player.GetPlayerLives() < 3)
{
int randomPowerUP = Random.Range(0, _utilitiesPowerups.Length);
Instantiate(_utilitiesPowerups[randomPowerUP], _utilityPowerUpSpawnPosition, Quaternion.identity);
}
else
Instantiate(_utilitiesPowerups[0], _utilityPowerUpSpawnPosition, Quaternion.identity);
yield return new WaitForSeconds(Random.Range(5, 11));
}
}

In the code above, we now have a variable that holds our Player for the SpawnManager. We grab a handle at the start, and null check it.
Them we have our new SpawnUtilityPowerUpRoutine, that will take care of spawning both Ammo and Life powerups. They are assigned a random position to spawn within the X axis, and we check if the player currently has less than 3 lives. If he does, we randomly spawn a powerup from the array. Otherwise, we spawn the Ammo powerup.

public int GetPlayerLives()
{
return _playerLives;
}

We have to make sure that our player has a way to expose the value of its current lives, so we created a method for it. Now all we have to do is start the coroutine in our spawn manager and test it out.

public void StartSpawning()
{
StartCoroutine(EnemySpawnRoutine());
StartCoroutine(SpawnPowerUpRoutine());
StartCoroutine(SpawnUtilityPowerUpRoutine());
}

Now that we have our powerup spawning properly, lets make sure it does what we want, give our player some lives back!

public void GrantBonusLife()
{
_playerLives++;
_playerLives = Mathf.Clamp(_playerLives, 0, 3);
_uiManager.UpdateLivesDisplay(_playerLives);
}

This method grants our player +1 life when called, and after the life is given, it makes sure to Clamp the value to a max of 3, since that’s our maximum amount of lives, and the display of lives that we have.

private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
Player player = other.GetComponent<Player>();
if (player != null)
{
ActivatePowerUp(player);
}
Destroy(gameObject);
}
}
private void ActivatePowerUp(Player player)
{
AudioSource.PlayClipAtPoint(_powerUpClip, transform.position);
switch (_type)
{
case PowerUpType.TripleShot:
player.ActivateTripleShotPowerUp(_duration);
break;
case PowerUpType.Speed:
player.ActivateSpeedPowerUp(_duration);
break;
case PowerUpType.Shield:
player.ActivateShieldPowerUp();
break;
case PowerUpType.Ammo:
player.GrantBonusAmmo();
break;
case PowerUpType.Life:
player.GrantBonusLife();
break;
default:
break;
}
}

This update for our Powerup script adds the call of the method for our player when it collects a Life type powerup.

We can see both our powerups spawning, and the player receiving life as intended.

Now when we are at maximum lives, we always will receive the Ammo powerup, but otherwise, we have a chance to have a Life powerup spawned instead.

And for the last thing, when we get our Life powerup, our wings are still burning, so we need to make sure that the effect is removed from one of our wings, if not both.

private void SetAllWings(bool active)
{
foreach (var wings in _wings)
{
wings.SetActive(active);
}
}

private void SetRandomWingEffect(bool active)
{
int randomNumber = Random.Range(0, _wings.Length);
_wings[randomNumber].SetActive(active);
}

With this modification to our WingEffect methods, we can now pass either true or false as a parameter, and it will change a random wing to either active or inactive, and the other will set all wings to either active, or inactive.

public void GrantBonusLife()
{
_playerLives++;
_playerLives = Mathf.Clamp(_playerLives, 0, 3);
_uiManager.UpdateLivesDisplay(_playerLives);

if (_playerLives == 3)
SetAllWings(false);
else
SetRandomWingEffect(false);
}

With this last change, after receiving our life, if we are at full health, we just turn off all wing effects, otherwise, we just randomly turn off one of them.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response