97 lines
4.6 KiB
C#
97 lines
4.6 KiB
C#
using UnityEngine; // 유니티 기능을 불러올거에요 -> UnityEngine을
|
|
using UnityEngine.UI; // UI 기능을 불러올거에요 -> UnityEngine.UI를
|
|
using TMPro; // TextMeshPro를 사용할거에요 -> TMPro를
|
|
|
|
/// <summary>
|
|
/// 몬스터 체력바 UI — MonsterClass.OnHealthChanged 이벤트 연동
|
|
/// 몬스터 프리팹의 MonsterHP_Canvas에 부착
|
|
/// </summary>
|
|
public class MonsterHPUibar : MonoBehaviour // 클래스를 선언할거에요 -> 몬스터 체력바 UI를
|
|
{
|
|
[Header("--- 타겟 ---")] // 인스펙터 제목을 달거에요 -> 타겟 설정을
|
|
[Tooltip("MonsterClass가 붙어있는 몬스터 오브젝트")]
|
|
[SerializeField] private GameObject targetObject; // 변수를 선언할거에요 -> 타겟 오브젝트를 (몬스터 루트)
|
|
|
|
[Header("--- UI 요소 ---")] // 인스펙터 제목을 달거에요 -> UI 요소를
|
|
[Tooltip("HP_Filled (Image, Fill 방식)")]
|
|
[SerializeField] private Image hpFilledImage; // 변수를 선언할거에요 -> 체력바 Fill 이미지를
|
|
|
|
[Tooltip("HP_Text (TMP) — '현재HP / 최대HP' 표시")]
|
|
[SerializeField] private TextMeshProUGUI hpText; // 변수를 선언할거에요 -> 체력 텍스트를
|
|
|
|
// 캐싱된 참조
|
|
private MonsterClass _monster; // 변수를 선언할거에요 -> 몬스터 클래스 참조를
|
|
|
|
private void Awake() // 함수를 실행할거에요 -> 초기화 Awake를
|
|
{
|
|
// 타겟이 비어있으면 부모에서 자동으로 찾기
|
|
if (targetObject == null) // 조건이 맞으면 실행할거에요 -> 타겟이 설정 안 됐다면
|
|
{
|
|
targetObject = transform.root.gameObject; // 할당할거에요 -> 최상위 부모 오브젝트를
|
|
}
|
|
|
|
if (targetObject != null) // 조건이 맞으면 실행할거에요 -> 타겟이 있다면
|
|
{
|
|
_monster = targetObject.GetComponent<MonsterClass>(); // 가져올거에요 -> MonsterClass를
|
|
if (_monster == null) // 조건이 맞으면 실행할거에요 -> 직접 못 찾았다면
|
|
{
|
|
_monster = targetObject.GetComponentInParent<MonsterClass>(); // 가져올거에요 -> 부모에서 MonsterClass를
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnEnable() // 함수를 실행할거에요 -> 활성화 시 OnEnable을
|
|
{
|
|
if (_monster != null) // 조건이 맞으면 실행할거에요 -> 몬스터가 있다면
|
|
{
|
|
_monster.OnHealthChanged += OnMonsterHealthChanged; // 등록할거에요 -> 체력 변경 이벤트 리스너를
|
|
}
|
|
|
|
// 활성화 시 즉시 UI 갱신 (풀에서 재사용될 때 대비)
|
|
ResetUI(); // 실행할거에요 -> UI 초기화를
|
|
}
|
|
|
|
private void OnDisable() // 함수를 실행할거에요 -> 비활성화 시 OnDisable을
|
|
{
|
|
if (_monster != null) // 조건이 맞으면 실행할거에요 -> 몬스터가 있다면
|
|
{
|
|
_monster.OnHealthChanged -= OnMonsterHealthChanged; // 해제할거에요 -> 체력 변경 이벤트 리스너를
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// MonsterClass.OnHealthChanged(currentHP, maxHP) 이벤트 콜백
|
|
/// </summary>
|
|
private void OnMonsterHealthChanged(float currentHP, float maxHP) // 함수를 선언할거에요 -> 체력 변경 콜백을
|
|
{
|
|
// Fill Amount 갱신
|
|
if (hpFilledImage != null) // 조건이 맞으면 실행할거에요 -> Fill 이미지가 있다면
|
|
{
|
|
float ratio = (maxHP > 0) ? currentHP / maxHP : 0f; // 비율을 계산할거에요 -> 현재 / 최대로
|
|
hpFilledImage.fillAmount = Mathf.Clamp01(ratio); // 값을 설정할거에요 -> 0~1 사이로 Fill Amount를
|
|
}
|
|
|
|
// 텍스트 갱신
|
|
if (hpText != null) // 조건이 맞으면 실행할거에요 -> 텍스트가 있다면
|
|
{
|
|
hpText.text = $"{currentHP:F0} / {maxHP:F0}"; // 텍스트를 설정할거에요 -> "현재 / 최대" 형식으로
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// UI를 풀 체력 상태로 초기화 (스폰/재활성화 시)
|
|
/// </summary>
|
|
private void ResetUI() // 함수를 선언할거에요 -> UI 초기화를
|
|
{
|
|
if (hpFilledImage != null) // 조건이 맞으면 실행할거에요 -> Fill 이미지가 있다면
|
|
{
|
|
hpFilledImage.fillAmount = 1f; // 값을 설정할거에요 -> Fill을 꽉 채우기로
|
|
}
|
|
|
|
// _monster가 있으면 실제 스탯으로 텍스트 갱신
|
|
if (hpText != null) // 조건이 맞으면 실행할거에요 -> 텍스트가 있다면
|
|
{
|
|
hpText.text = ""; // 텍스트를 비울거에요 -> 초기화로 (첫 OnHealthChanged에서 갱신됨)
|
|
}
|
|
}
|
|
} |