インターフェースってどうやって使うの?【Unityで学ぶC#シリーズ】
似たような処理を異なるクラス間で実装したい時、インターフェースがとても便利です。どんな感じに使えば良いのかなどを実装を交えて解説したいと思います。
インターフェースの実装例
インターフェースって言われても困るわ!という人と、サンプル見たら思い出すわ!という人向け。
シチュエーション
ゲームなどで敵を攻撃したり、何かのオブジェクト(ここでは木)に攻撃があたった時などに何らかの処理を同様の手順で呼び出したいとします。今回はプレイヤー(Playerクラス)が敵(Enemyクラス)と木(Treeクラス)に接触した時にDamageメソッドを呼び出すことで実装したい処理を実現したこととします
各スクリプト&設定について
3つのクラス+1つのインターフェースは以下
using UnityEngine;
public class Player : MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D collision)
{
IDamaged[] damageArr = collision.GetComponentsInChildren<IDamaged>();
foreach (IDamaged d in damageArr) {
d.Damaged();
}
}
}
public interface IDamaged
{
void Damaged();
}
using UnityEngine;
public class Enemy : MonoBehaviour, IDamaged
{
public void Damaged()
{
Debug.Log("<color=yellow>敵</color>がダメージを受けました");
}
}
using UnityEngine;
public class Tree : MonoBehaviour, IDamaged
{
public void Damaged()
{
Debug.Log("<color=green>木</color>がダメージを受けました");
}
}
各オブジェクトにはBoxCollider2Dが付いていて、PlayerにはRigidBody2Dをつけています。インスペクターはこんな感じ。
動作結果
上記の設定で動かした場合、こんな感じのログが表示されます。プレイヤーを動かして、敵や木に触れたタイミングでデバッグログが表示されています。
実装目線で期待出来る部分
このような実装で期待できるポイントとしては、攻撃を行っている側(Playerクラス)が相手側のクラスが何なのかを知らない状態にも関わらず、それぞれのDamageメソッドを呼ぶことができているという点です。
これは今後プログラムを拡張する場合、Player側の処理を変更することなく新しくダメージを受ける処理を追加することが出来るということです。超便利!
インターフェースの実装方法
インターフェースを実装する場合、インターフェースとそれを実装するクラスを用意する必要があります。インターフェースを用意した後、それを呼び出すクラス内の処理を実装する必要があります。
実装に必要なもの
インターフェースを利用した処理を実現するには次の要素が必要になります。例としてIDamageというインターフェースを例に取って示したいと思います。
必要なもの | 実装ポイント |
インターフェース自身 | public interface IDamage{ void Damaged(); } |
インターフェスを 装着する人 | public class Sample MonoBehaviour , IDamage{ public void Damage{ // ダメージを受けた処理; } } |
インターフェースを 介して呼び出す人 | IDamage d = GetComponent<IDamage>(); d.Damaged(); |
ざーっとまとめるとこんな感じ。
どういう時に使うべきか
まぁ基本的には困った時に使えというのが基本ですね。
例で出したような当たり判定での実装は活躍の場が多いと思います。一般的に最初に習う方法としては当たった相手のTag(タグ)で判別したり、GetComponentでクラス自体を取得して処理を行ったりすると思います。
プログラム学びたての状態だとクラス自身のメソッドを呼び出したりするほうが直感的でわかりやすいと思います。インターフェースを利用した方法が拡張性もあって大変便利ではありますが、プログラムに慣れてからが良いと思います。