이벤트로 UI 제어하기
Coddy Unity 여정의 Unity 게임 아키텍처 섹션에 포함된 레슨. 64개 중 15번째.
이벤트를 사용하면 HUD는 게임의 변화를 따르지만, 게임은 HUD가 있는지조차 모릅니다. 이 Health는 체력 포인트를 관리하고 두 가지를 알립니다. 체력이 바뀌었고, 체력이 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을 호출하지만, 호출 순서는 보장되지 않습니다. 따라서 막대의 OnEnable이 Health의 Awake에서 Hp를 설정하기 전에 실행될 수 있고, 그러면 막대에 0이 표시됩니다. 어떤 Start가 실행되기 전까지는 모든 Awake가 실행됩니다.
챌린지
쉬움총이 변경 사항을 알리고 HUD가 이를 듣게 하세요.
Gun.cs에서using System;,public event Action<int, int> OnAmmoChanged및public event Action<bool> OnReloading을 추가하고, 주석에 표시된 곳에서 이벤트를 발생시키세요.AmmoHud.cs에서OnEnable에 구독하고OnDisable에서 구독을 해제하세요.ammoText에는Ammo: 4/6이 표시되고,reloadText는 재장전 중일 때만 표시됩니다.Start에서gun.Ammo와gun.Reloading을 한 번 표시하세요.
‘플레이’를 누르고 총을 두 번 비우세요. 그런 다음 ‘확인’을 누르세요.
직접 해보기
using UnityEngine;
using TMPro;
public class AmmoHud : MonoBehaviour
{
public Gun gun;
public TMP_Text ammoText;
public GameObject reloadText;
}
Unity 게임 아키텍처의 모든 레슨
직접 연습해 보세요: Unity 플레이그라운드