UnityEventフィールド
CoddyのUnityジャーニー「Unityにおけるゲームアーキテクチャ」セクションの一部。レッスン 12/50。
ボタンの On Click () は 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();
}
}
}インスペクターの On Finished () には、ボタンと同じように行を追加できます。1つの行でロケットを発射し、別の行でゲートを開きます。別のレベルでは、同じ Countdown を別の行で再利用でき、新しいスクリプトを書く必要はありません。UnityEvent<int> は値を渡します。ドロップダウンでは、int を受け取るメソッドが Dynamic int の下に表示され、その行には Invoke に渡された値、この例では残り秒数が渡されます。同じメソッドでも Static Parameters の下にあるものを選ぶと、代わりに行に入力した数値が渡されます。また、パラメーターのないメソッドも割り当てられます。
Unity はスクリプトの読み込み時に UnityEvent フィールドを作成するため、onTick が null になることはなく、?. も必要ありません。また、コードから onTick.AddListener(ShowSeconds) を使ってリスナーを追加できます。オブジェクトごとに反応が異なり、インスペクターで設定する場合は、自分自身やスクリプトを開かないデザイナーが設定する場合も含め、UnityEvent を選びましょう。コードでリッスンする場合は C# イベントを選びましょう。コンパイラーがメソッド名をチェックするため、名前を変更すると、気づかれないまま <Missing> の行が残るのではなく、ビルドが失敗します。また、C# イベントはインスペクターには表示されません。
チャレンジ
簡単島を周回する3周レースです。矢印で車を操作します(Car.cs)。シーンは、デザイナーがインスペクターで設定するように配線されています。FinishLine の On Lap (Int32) リストは、LapText 上の LapBoard.ShowLaps(Dynamic int)と Crowd 上の Crowd.Cheer を呼び出し、On Race Over () リストは LapBoard.ShowFinished と Car.Stop を呼び出します。これらのスクリプトは準備できていますが、FinishLine にイベントが追加されるまでは、リストにアタッチするものがありません。
FinishLine.cs を記述してください。
- UnityEvent フィールドを2つ用意します。
onLapは int を渡し、onRaceOverは何も渡しません。 - 車(タグが
Player)がラインに入るたびに、1周が完了します。完了した周回数(1、次に2、次に3)を渡してonLapを呼び出します。ラインを通過する他のものはカウントしません。 - 完了した周回数が
laps(3)に達したら、onRaceOverを呼び出します。その後は、ラインを通過しても何も起こりません。
Play を押して、島を3周運転してから、Check を押してください。
自分で試してみよう
using UnityEngine;
public class FinishLine : MonoBehaviour
{
public int laps = 3;
void OnTriggerEnter(Collider other)
{
// 車がラインを通過した:さらに1周完了
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。