Menu
CoddyTech

IDamageable

CoddyのUnityジャーニー「Unityのゲームアーキテクチャ」セクションの一部。レッスン 7/64。

インターフェースとは、クラスが実装することを約束するメソッドの一覧で、その中にコードはありません。ほかに共通点のないクラス同士でも、同じ約束をできます。通常の C# では次のようになります。

interface IGreeter
{
    string Greet();
}

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

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

IGreeter型の変数にはRobotまたはCatを入れることができ、greeter.Greet()を実行すると、その変数に入っている方のメソッドが呼び出されます。IGreeterを宣言しているクラスに、publicなGreet()がない場合、コンパイルできません。

ゲームでは、ダメージを受けるものがたくさんありますが、それ以外の共通点はほとんどありません。プレイヤーにはヒットポイントがあり、木箱は最初の攻撃で壊れます。共通の基底クラスを使うと、これらを1つの系統に押し込むことになります。インターフェースは共通する1つの性質に名前を付け、それぞれのスクリプトが独自の方法で実装できます。

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);
    }
}

スクリプトが持てる基底クラスは引き続き1つで、インターフェースはその後に列挙します。インターフェースは専用のファイルIDamageable.csに置き、MonoBehaviourを継承しません。コンポーネントではないため、それ自体をオブジェクトに追加することはありません。インターフェースを宣言したクラスには、publicなTakeDamage(int)が必要です。そうでなければコンパイルできません。

ダメージを与える側は、クラスではなくインターフェースを要求します。

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

この同じコードで、火の玉はプレイヤーにダメージを与え、木箱を壊せます。後から別の種類の対象を追加しても、ここを変更する必要はありません。Unityでは、インターフェース型のフィールドはInspectorに表示されません。そのため、火の玉の例のように、スクリプトはGameObjectまたはコンポーネントを保持し、それにインターフェースを問い合わせます。

challenge icon

チャレンジ

簡単

雪だるま、ベル、かかしを IDamageable にして、ハンマーが攻撃できるようにしましょう。

  1. Snowman: TakeDamage を受けるたびに、すべての軸で 0.25f * amount だけ縮小します。0.5 以下になったら破壊します。
  2. Bell: 1ポイントごとに Dong をログに記録し、amount を rings に加算します。
  3. Scarecrow: 最初の攻撃時にのみ transform.Rotate(0f, 0f, 90f); を実行します。
  4. Slam で、各コライダーに IDamageable があれば、その TakeDamage(power) を呼び出します。

「プレイ」を押して、それぞれを攻撃しましょう。その後、「確認」を押します。

自分で試してみよう

using UnityEngine;

public class Snowman : MonoBehaviour
{
}

Unityのゲームアーキテクチャのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド