[unity] インスペクターで interface を使用する
[SerializeField] SerializableInterface<IEnemy> enemy;
unity 標準の機能では、interface をインスペクターに表示できない。
でも、使いたい。そんな場合に便利なアセット、SerializableInterface を紹介します。
掲載サイト
OpenUPM を使ってインストールします。
OpenUPM ってなんのこっちゃ? という人が多いかもしれませんが、PackageManager 経由で取得できる方法があります。
OpenUPM
まず、掲載サイトの URL (https://openupm.com/packages/net.tnrd.serializableinterface/) のうち、net.tnrd.serializableinterface
が必要です。
(これをスコープといいます。コピーしておきましょう)
unity の Edit > Project Settings > Package Manager を開きます。
Name: OpenUPM
URL: https://package.openupm.com
Scope(s): net.tnrd.serializableinterface
次のように記述し、save します。
Package Manager
次に Window > Package Manager を開きます。
左下のジグゾーパズルのようなマークをクリック。
Serializable Interface をインストールします。
使い方
サンプルの前準備として、EnemyA, EnemyB と、それを共通化するインターフェイス IEnemy を作成します。
public interface IEnemy
{
public void DebugLog();
}
using UnityEngine;
public class EnemyA : MonoBehaviour, IEnemy
{
public void DebugLog()
{
Debug.Log("EnemyA");
}
}
using UnityEngine;
public class EnemyB : MonoBehaviour, IEnemy
{
public void DebugLog()
{
Debug.Log("EnemyB");
}
}
次に、この EnemyA・EnemyB をインスペクターから登録できるクラス Main.cs を作成します。
using TNRD;
using UnityEngine;
public class Main : MonoBehaviour
{
[SerializeField] SerializableInterface<IEnemy> enemy;
void Start()
{
enemy.Value?.DebugLog();
}
}
SerializableInterface<IEnemy>
が最初のポイントです。
この Main を GameObject にアタッチしてください。
None(Object) というメンバーが表示されていれば成功です。
ここには IEnemy を継承したクラス(EnemyA、EnemyB)を入れて実行すると、それぞれの DebugLog() が実行されることを確認できます。
enemy.Value?.DebugLog();
と、Value を挟むのが次のポイントです。
? は null チェック不要であればつけなくても OK です。
そもそも interface って必要?
いろいろ流派もあるかと思いますが、個人的に interface は「適切に使えば、将来起こり得る問題を防ぎやすい」記法だと思います。
具体的に考察した記事もありますので、よければ一緒にご覧ください。
Discussion