Menu
CoddyTech

IDamageable

Part of the Game Architecture in Unity section of Coddy's Unity journey. Lesson 6 of 50.

Many things in a game can be hurt, and they have little else in common: the player has hit points, a crate breaks at the first hit. A shared base class would force them into one family. An interface names the one thing they share, and each script implements it in its own way:

public interface IDamageable
{
    void TakeDamage(int amount);
}
public class PlayerHealth : MonoBehaviour, IDamageable
{
    public int hp = 10;

    public void TakeDamage(int amount)
    {
        hp -= amount;
        Debug.Log("Ouch! hp: " + hp);
    }
}
public class Crate : MonoBehaviour, IDamageable
{
    public void TakeDamage(int amount)
    {
        Destroy(gameObject);
    }
}

A script still has one base class, MonoBehaviour, and lists interfaces after it. The interface goes in a file of its own, IDamageable.cs, and does not derive from MonoBehaviour: it is not a component and never goes on an object by itself. A class that lists it must have a public TakeDamage(int), or it does not compile.

Whatever does the damage asks for the interface, not for a class:

// Fireball.cs
void OnCollisionEnter(Collision collision)
{
    IDamageable target = collision.gameObject.GetComponent<IDamageable>();
    if (target != null)
    {
        target.TakeDamage(3);
    }
    Destroy(gameObject);
}

The fireball hurts the player and breaks crates with the same lines, and a kind of target added later needs no change here. Unity does not show a field of an interface type in the Inspector, so scripts hold a GameObject or a component and ask it for the interface, as the fireball does.

challenge icon

Challenge

Easy

A giant guards the village square. The arrows walk the Giant (Mover.cs, ready), and Space swings its hammer: Hammer.cs calls Slam(), which finds every collider within radius. Three things in the square take a hit, each in its own way, and share nothing else:

  • Snowman: each point of damage takes 0.25 off its size on every axis (it starts at 1.5). At a size of 0.5 or less it melts: destroy the snowman.
  • Bell: logs Dong once per point of damage (a hit of 2 logs it twice) and adds the points to rings.
  • Scarecrow: the first hit tips it over, turning it 90 degrees around z, whatever the damage. Later hits change nothing.

IDamageable.cs declares the interface, with one method: void TakeDamage(int amount). Make Snowman, Bell and Scarecrow implement it, each with its own reaction. Then, in Slam, call TakeDamage(power) on the IDamageable of each collider it finds. Colliders without one, such as the ground, are skipped.

Press Play, walk up to each of them and swing, then Check.

Try it yourself

using UnityEngine;

public class Snowman : MonoBehaviour
{
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Game Architecture in Unity