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
EasyMake the snowman, bell and scarecrow IDamageable, so the hammer hits them.
Snowman:TakeDamageshrinks it0.25f * amounton every axis; at 0.5 or less, destroy it.Bell: logDongonce per point and addamounttorings.Scarecrow: only the first hit runstransform.Rotate(0f, 0f, 90f);.- In
Slam, callTakeDamage(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
1Components, Not Hierarchies
Small ComponentsA Base Enemy ScriptAbstract ComponentsComponents Working TogetherRecap: Modular TurretRecap: Twin Cannon4Serialized Data
Serializable ClassesLists in the InspectorEnums in the InspectorRecap: Loot TableRecap: Roll the Loot2Interfaces in Unity
IDamageableInterfaces and TryGetComponentGetComponentsRecap: Interact KeyRecap: Nearest in ReachPractice on your own: Unity playground