SerializeReference属性を利用すれば抽象型やインタフェース型のフィールドをシリアライズできます。
しかし、Monobehaviorを継承していない場合に限るので少々使い勝手が悪いです。
そこで、Monobehaviorを継承したクラスのインターフェースを[SerializeField]で渡すための仲介クラスを作っていきます
InterfaceMediater クラス
public class InterfaceMediater<TInterface>
{
[SerializeField] GameObject _objectI;
TInterface _interface;
public TInterface Interface()
{
if (_objectI)
{
_objectI.TryGetComponent<TInterface>(out _interface);
}
return _interface;
}
}
Unity2020.1からGenericな型がシリアライズ可能になっていますので、Monobehaviorを継承しないこのクラスを作成し、受け取り側でInterfaceMediater型の変数を宣言し使います。
使い方
Itestインターフェースには”取得完了”とだけ表示するTest()関数が定義されています
public class CodeReadTestScript : MonoBehaviour
{
[SerializeField] InterfaceMediater<ITest> _tsetInterface;
private void Start()
{
var testI = _tsetInterface.Interface();
testI.Test();
}
}
[SerializeField]属性を付けてInterfaceMediater型の変数をインターフェース名を指定しながら宣言します
その変数からアクセスできるInterface()関数は指定したインターフェースのみを返します。
インスペクターにはこのように表示されており、このObject I に取得したいインターフェースを持ったオブジェクトをアタッチすることでInterface()関数を通してインターフェースのみを取得できます。
実行結果
このように取得したインターフェースを経由して関数を実行することが出来ます。
終わりに
インターフェースを利用し依存性の逆転を行うことで疎結合を実現できます。
今回は、せっかく実現したその疎結合を[SerializeField]でGameObjectをアタッチするなどして台無しにしないように、Monobehaviorを継承したクラスのインターフェースのみを[SerializeField]で受け渡す方法を記事にしました。