UnityAction型はUnityが用意しているデリゲートです。デリゲートはわかりやすくいうと、メソッドを代入することができる型(変数)です。
UnityAction型はUnityEngine.Eventsとして名前空間に定義されていてますので、使用する場合には宣言が必要です。
一時的に使うだけならそのときに1回だけ宣言しても利用できますが、usingで宣言しておきましょう。
using UnityEngine.Events;
UnityAction型はデリゲートですので、下記のようにメソッドを代入することが出来ます。
戻り値を持つメソッド
public UnityAction GetSkill(SkillType chooseSkillType) {
switch (chooseSkillType) {
case SkillType.DeleteMaxEtoType:
return DeleteMaxEtoType; <= DeleteMaxEtoTypeメソッドをUnityAction型として代入している
// TODO スキルが増えた場合には追加する
}
return null;
}
そのため次のメソッドの引数には、DeleteMaxEtoTypeというメソッドがUnityActionの値として代入されていることになります。
public IEnumerator SetUpSkillButton(UnityAction unityAction) { <= この変数には、GetSkill(skillType)の処理結果 = DeleteMaxEtoTypeというメソッドが代入されている
// UnityEventにunityActionを登録(UnityActionにはメソッドが代入されている)
unityEvent.AddListener(unityAction); <= このAddListnerメソッドに登録される値は、DeleteMaxEtoTypeというメソッドになります
デリゲートを使用することによって、メソッドも変数の値として代入し、他の引数と同じように同じ型内での受け渡しが可能になります。
処理を順番に読み解いてみましょう。
<EnemyController.cs>
// 変数を用意する
private UnityAction<Transform, float> moveEvent;
ここに移動用のメソッドを取得して代入します。
// MoveEventSO スクリプタブル・オブジェクトの GetMoveEvent メソッドを実行し、戻り値で移動用のメソッドを受け取る。ここで移動方法を決定
moveEvent = this.enemyGenerator.moveEventSO.GetMoveEvent(enemyData.moveType);
↓ 右辺の処理は、以下の通り
<MoveEventSO スクリプタブル・オブジェクト GetMoveEvent メソッド。moveType で分岐し、UnityActon<Transform, float> 型で値が戻る>
public UnityAction<Transform, float> GetMoveEvent(MoveType moveType) {
switch (moveType) {
case MoveType.Straight:
return MoveStraight;
case MoveType.Meandering:
return MoveMeandering;
case MoveType.Boss_Horizontal:
return MoveBossHorizontal;
default:
return Stop;
}
}
↓ 右辺の処理が終了すると、
エネミーの moveType に応じた移動用のメソッドが1つだけ戻り値として取得できる
<EnemyController.cs>
// MoveEventSO スクリプタブル・オブジェクトの GetMoveEvent メソッドを実行し、戻り値で移動用のメソッドを受け取る。ここで移動方法を決定
// どちらも UnityAction<Transform, float> であるので、代入が成立する
moveEvent = UnityAction<Transform, float> 型のメソッドが1つ戻ってくる
↓
moveEvent 変数には移動用のメソッドが登録されているので、Invoke メソッドを実行して処理をする
// Invoke メソッドを実行すると、moveEvent 変数に登録されたメソッド(今回は移動用のメソッド)を実行する。UnityActon <Transform, float>型なので、実行にあたって、指定された型の情報を指定する
moveEvent.Invoke(transform, enemyData.moveDuration);
変数の中にメソッドが登録できる、というのは不思議に思えるかもしれませんが、以前からこれに近い処理は実装しています。
Button クラスの
AddListener メソッドがこれに当たります。引数に、ボタンを押した際に実行したいメソッドを登録していたはずです。
今回の UnityAction の機能でポイントとなるのは、
移動用のメソッドに対して必要な引数の情報を型パラメータという形で指定していることです。
UnityAction<Transform, float> 型とは、
すべての移動用のメソッドで使用する引数の型を指定していることが分かります。
確認してみましょう。
<MoveEventSO スクリプタブル・オブジェクト>
public void MoveStraight(Transform tran, float duration) {
//Debug.Log(tran);
Debug.Log("直進");
tran.DOLocalMoveY(moveLimit, duration);
}
デリゲートには複数のメソッドを登録して順番に実行するという機能もありますし、実行するタイミングを自分で設定できるので、活用できると便利な機能になります。
少しずつ覚えていきましょう。