Menu
CoddyTech

イベントでUIを動かす

CoddyのUnityジャーニー「Unityにおけるゲームアーキテクチャ」セクションの一部。レッスン 13/50。

イベントを使うと、ゲーム側はHUDのことを何も知らないまま、HUDがゲームに追従します。このHealthはヒットポイントを管理し、2つのことを通知します。体力が変化したこと、そして0になったことです。バーやテキスト、ゲームオーバー画面用のフィールドはないため、同じコンポーネントをプレイヤーにも、HUDのない敵にも、テストシーンにも使えます。

public class Health : MonoBehaviour
{
    public int maxHp = 100;
    public event Action<int, int> OnChanged;
    public event Action OnDied;
    public int Hp { get; private set; }

    void Awake()
    {
        Hp = maxHp;
    }

    public void TakeDamage(int amount)
    {
        if (Hp == 0) return;
        Hp = Mathf.Max(Hp - amount, 0);
        OnChanged?.Invoke(Hp, maxHp);
        if (Hp == 0) OnDied?.Invoke();
    }
}
// HealthBar.cs、HUD上に配置
public Health health;
public Image bar;

void OnEnable() { health.OnChanged += Show; }
void OnDisable() { health.OnChanged -= Show; }

void Start()
{
    Show(health.Hp, health.maxHp);
}

void Show(int hp, int max)
{
    bar.fillAmount = (float)hp / max;
}

バーは、OnEnableとOnDisableの組み合わせによって、アクティブな間だけイベントを購読します。イベントは両方の数値を渡すので、ShowはHealthからほかに何も受け取る必要がありません。GameOverScreenはパネルを表示するためにOnDiedを購読し、ダメージ音はOnChangedを購読します。それぞれ別のスクリプトで処理され、Healthはどちらのためにも変更する必要がありません。Hp { get; private set; }を使えば、HUDは体力を読み取れますが、変更はできません。

イベントは変化を通知するため、最初に攻撃を受けるまではバーには何も通知されません。現在の体力はStartで一度描画します。OnEnableでは描画しません。UnityはオブジェクトごとにAwakeを呼び、その後OnEnableを呼びますが、その順序は保証されていません。そのため、HealthのAwakeでHpが設定される前に、バーのOnEnableが実行されてしまい、バーには0が表示される可能性があります。Startが実行される頃には、すべてのAwakeが実行済みです。

challenge icon

チャレンジ

簡単

射撃場です。Space キーで銃(Gun.cs)を撃ちます。銃には maxAmmo(6 発)があり、最後の 1 発を撃つと reloadTime(1.5 秒)のリロードが始まり、弾が補充されます。HUD にはまだ何も表示されません。銃に変更を通知させ、HUD がその通知を受け取るようにしましょう。銃に HUD 用のフィールドは追加しません。

  • Gun.cs に、次の 2 つの public イベントを追加します。弾数と maxAmmo(どちらも int)を渡す OnAmmoChanged と、bool を渡す OnReloading です。リロード開始時は true、終了時は false を渡します。コメントの指示に従ってイベントを発行してください。
  • HUD 上の AmmoHud.cs で、HUD がアクティブな間、両方のイベントを受け取ります。ammoText には弾数を Ammo: 4/6 と表示し、reloadText(Reloading... というテキストを含むオブジェクト)はリロード中だけ表示します。
  • 最初の発砲より前から、HUD に正しい情報を表示します。Ammo: 6/6 と表示し、リロードのテキストは表示しません。銃の Ammo プロパティと Reloading プロパティから、現在の値を取得できます。
  • HUD が破棄されても、銃はエラーを起こさずに撃ち続けられます。

Play を押し、銃の弾を 2 回撃ち切ってから、Check を押してください。

自分で試してみよう

using UnityEngine;
using TMPro;

public class AmmoHud : MonoBehaviour
{
    public Gun gun;
    public TMP_Text ammoText;
    public GameObject reloadText;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Unityにおけるゲームアーキテクチャのすべてのレッスン