Day 135 — Creating Universal Health Damage

Connor Fullarton
4 min readJul 28, 2021

Hey and welcome!

In this one we’re going to look into creating a damage system that can be shared by the enemies and the player but this time round it’s going to be a little different as we’ll do this without the use of interfaces.

Go ahead and create a Health script to attach to your Enemy and Player objects and then add in this code to it:

[SerializeField]
private int _maxHealth;
[SerializeField]
private int _minHealth;
[SerializeField]
private int _currentHealth;
private void Start()
{
_currentHealth = _maxHealth;
}

Right away this sets us up with universal health that we can change and customise between our Player and Enemy thanks to our use of serializing the field for each variable here. At the start of the game we’re also going to assign the max health to the current health so the current health value can remain as 0.

Now let’s complete this script by adding in a public Damage() method that we can call:

public void Damage(int damageAmount)
{
_currentHealth -= damageAmount;
if (_currentHealth < _minHealth)
{
Destroy(this.gameObject);
}
}

As with our damage code in the past we’re just subtracting a certain amount of damage from our current health and if our current health is less than 0 then we will destroy the object that this script is assigned to.

Let’s make use of this now by adding in the following code to our Shoot script:

if (Input.GetMouseButtonDown(0))
{
Vector3 center = new Vector3(0.5f, 0.5f, 0);
Ray rayOrigin = Camera.main.ViewportPointToRay(center);
RaycastHit hitInfo;
if (Physics.Raycast(rayOrigin, out hitInfo))
{
Debug.Log("Hit: " + hitInfo.collider.name);
Health health = hitInfo.collider.GetComponent<Health>();
if (health != null)
{
health.Damage(50);
}

}
}

This bit of code gets the Health script/component from the object that our ray collides with and if that object does have Health on it then we run the Damage() function and take off 50 damage per hit.

Lastly, let’s create an attack system for our enemy so that they can damage the player when they get close. If you have a box collider on your enemy currently go ahead and remove it and replace it with a sphere collider that stretches out beyond the enemy.

Make sure that it’s set as a trigger collider as well. When you’ve done that you can then add in this code to the EnemyAI script:

public enum EnemyState
{
Idle,
Chase,
Attack
}
[SerializeField]
private EnemyState _currentState = EnemyState.Chase;
private Health _playerHealth;
private float _attackDelay = 1.5f;
private float _nextAttack = -1f;
void Start()
{
_controller = GetComponent<CharacterController>();
_player = GameObject.FindGameObjectWithTag("Player").transform;
_playerHealth = _player.GetComponent<Health>();
}
void Update()
{
if (_currentState == EnemyState.Chase)
{

Movement();
}
if (_currentState == EnemyState.Attack)
{
if (Time.time > _nextAttack)
{
_playerHealth.Damage(35);
_nextAttack = Time.time + _attackDelay;
}
}
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
_currentState = EnemyState.Attack;
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
{
_currentState = EnemyState.Chase;
}
}

By using an enum we’re able to create a state machine that holds an Idle, Chase and Attack state for our enemy which we can set by creating a _currentState variable with the type of our enum.

We make use of this by executing the movement code we made for our enemy last time when the state is set to Chase. Then if the enemy’s sphere collides with the player the state will switch to Attack where we execute coder very similar to our shoot system from the space shooter that damages the player every 1.5f for 35 damage. As a little reminder Time.time is used to get the current amount of time that the game has been running for.

Lastly when the player exits the sphere collider we set the state back to Chase which executes the movement code once more.

With all that done you should have the above working for you! We’ll clean this up later so that our Player object will get destroyed without this affecting our camera.

--

--

Connor Fullarton

Hey and welcome! My name is Connor and my goal here is to put out a daily post for a full year about my game development journey.