UnityEventフィールド
CoddyのUnityジャーニー「Unityのゲームアーキテクチャ」セクションの一部。レッスン 14/64。
ボタンの「クリック時 ()」はUnityEventフィールドで、自分のスクリプトにも同じものを持たせられます。publicなUnityEventフィールドはインスペクターに同じ種類のリストとして表示され、スクリプトは何が接続されているかを知らなくてもInvoke()でイベントを発生させます。このカウントダウンは1秒ごとに刻みます。
using UnityEngine;
using UnityEngine.Events;
public class Countdown : MonoBehaviour
{
public int seconds = 3;
public UnityEvent<int> onTick;
public UnityEvent onFinished;
void Start()
{
InvokeRepeating("Tick", 1f, 1f);
}
void Tick()
{
seconds--;
onTick.Invoke(seconds);
if (seconds == 0)
{
CancelInvoke("Tick");
onFinished.Invoke();
}
}
}インスペクターでは、終了時 ()にもボタンと同じように行を追加できます。1つの行でロケットを発射し、別の行でゲートを開きます。別のレベルでは、同じCountdownを別の行と一緒に再利用でき、新しいスクリプトを書く必要はありません。UnityEvent<int>は値を渡します。ドロップダウンでは、intを受け取るメソッドが動的 intの下に表示され、その行にはInvokeに渡された値(この例では残りの秒数)が渡されます。同じメソッドでも「静的パラメーター」の下にあるものを選ぶと、代わりに行に入力した数値が使われます。また、パラメーターを受け取らないメソッドも接続できます。
Unityはスクリプトを読み込むときにUnityEventフィールドを作成するため、onTickがnullになることはなく、?.も必要ありません。また、コードからonTick.AddListener(ShowSeconds)でリスナーを追加できます。オブジェクトごとに反応が異なり、スクリプトを開かないデザイナーや自分がインスペクターで設定する場合は、UnityEventを選びましょう。コードからリスナーを設定する場合は、C#イベントを選びましょう。コンパイラーがメソッド名をチェックするため、名前を変更すると、何も表示されないまま<Missing>の行が残るのではなく、ビルドが失敗します。また、C#イベントはインスペクターには表示されません。
チャレンジ
簡単FinishLineに、シーンのイベント行が接続されているイベントを追加しましょう。
using UnityEngine.Events;、public UnityEvent<int> onLap;、public UnityEvent onRaceOver;と、完了した周回数を保持するprivateなintを追加します。OnTriggerEnterで、otherにPlayerタグが付いている場合、周回数を数え、完了した周回数を引数としてonLap.Invokeを呼び出します。lapsに達したら、onRaceOver.Invoke()を呼び出します。その後は、ラインを通過しても何も起こりません。
「プレイ」を押して、3周走りましょう。それから「確認」を押します。
自分で試してみよう
using UnityEngine;
public class FinishLine : MonoBehaviour
{
public int laps = 3;
void OnTriggerEnter(Collider other)
{
// 車がラインを通過した:もう1周完了
}
}
Unityのゲームアーキテクチャのすべてのレッスン
自分で練習してみよう: Unityプレイグラウンド