Menu
CoddyTech

IDamageable

Part of the Game Architecture in Unity section of Coddy's Unity journey. Lesson 7 of 64.

An interface is a list of methods a class promises to have, with no code in them. Classes that have nothing else in common can make the same promise. In plain C#:

interface IGreeter
{
    string Greet();
}

class Robot : IGreeter
{
    public string Greet() { return "Beep"; }
}

class Cat : IGreeter
{
    public string Greet() { return "Meow"; }
}

A variable of type IGreeter can hold a Robot or a Cat, and greeter.Greet() runs whichever it holds. A class that lists IGreeter but has no public Greet() does not compile.

In a game, many things 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

Make the snowman, bell and scarecrow IDamageable, so the hammer hits them.

  1. Snowman: TakeDamage shrinks it 0.25f * amount on every axis; at 0.5 or less, destroy it.
  2. Bell: log Dong once per point and add amount to rings.
  3. Scarecrow: only the first hit runs transform.Rotate(0f, 0f, 90f);.
  4. In Slam, call TakeDamage(power) on each collider's IDamageable, if any.

Press Play and swing at each. Then Check.

Try it yourself

using UnityEngine;

public class Snowman : MonoBehaviour
{
}

All lessons in Game Architecture in Unity

Practice on your own: Unity playground