using UnityEngine; // 유니티 기능을 불러올거에요 -> UnityEngine을 using UnityEngine.UI; // UI 기능을 불러올거에요 -> UnityEngine.UI를 using TMPro; // TextMeshPro를 사용할거에요 -> TMPro를 /// /// 플레이어 체력바 UI — PlayerHealth 이벤트 연동 /// HP_Filled (Image Fill) + Text (TMP) 실시간 갱신 /// public class HPUibar : MonoBehaviour // 클래스를 선언할거에요 -> 체력바 UI를 { [Header("--- 타겟 ---")] // 인스펙터 제목을 달거에요 -> 타겟 설정을 [SerializeField] private GameObject targetObject; // 변수를 선언할거에요 -> 타겟 오브젝트를 (Player) [Header("--- UI 요소 ---")] // 인스펙터 제목을 달거에요 -> UI 요소를 [Tooltip("HP_Filled (Image, Fill 방식)")] [SerializeField] private Image hpFilledImage; // 변수를 선언할거에요 -> 체력바 Fill 이미지를 [Tooltip("Text (TMP) — '현재HP / 최대HP' 표시")] [SerializeField] private TextMeshProUGUI hpText; // 변수를 선언할거에요 -> 체력 텍스트를 // 캐싱된 참조 private PlayerHealth _playerHealth; // 변수를 선언할거에요 -> 플레이어 체력 스크립트를 private Stats _playerStats; // 변수를 선언할거에요 -> 플레이어 스탯 스크립트를 private void Awake() // 함수를 실행할거에요 -> 초기화 Awake를 { if (targetObject != null) // 조건이 맞으면 실행할거에요 -> 타겟이 있다면 { _playerHealth = targetObject.GetComponent(); // 가져올거에요 -> PlayerHealth를 _playerStats = targetObject.GetComponent(); // 가져올거에요 -> Stats를 } } private void OnEnable() // 함수를 실행할거에요 -> 활성화 시 OnEnable을 { if (_playerHealth != null) // 조건이 맞으면 실행할거에요 -> 체력 스크립트가 있다면 { _playerHealth.OnHealthChanged.AddListener(OnHealthRatioChanged); // 등록할거에요 -> 체력 변경 이벤트 리스너를 } } private void OnDisable() // 함수를 실행할거에요 -> 비활성화 시 OnDisable을 { if (_playerHealth != null) // 조건이 맞으면 실행할거에요 -> 체력 스크립트가 있다면 { _playerHealth.OnHealthChanged.RemoveListener(OnHealthRatioChanged); // 해제할거에요 -> 체력 변경 이벤트 리스너를 } } private void Start() // 함수를 실행할거에요 -> 시작 시 Start를 { UpdateUI(); // 실행할거에요 -> 초기 UI 갱신을 (시작하자마자 올바른 값 표시) } /// /// PlayerHealth.RefreshHealthUI()에서 ratio(0~1)를 받아 호출됨 /// private void OnHealthRatioChanged(float ratio) // 함수를 선언할거에요 -> 체력 비율 변경 콜백을 { // Fill Amount 갱신 if (hpFilledImage != null) // 조건이 맞으면 실행할거에요 -> Fill 이미지가 있다면 { hpFilledImage.fillAmount = Mathf.Clamp01(ratio); // 값을 설정할거에요 -> 0~1 사이로 Fill Amount를 } // 텍스트 갱신 UpdateHPText(); // 실행할거에요 -> 텍스트 갱신 함수를 } /// /// 텍스트를 "현재HP / 최대HP" 형식으로 갱신 /// private void UpdateHPText() // 함수를 선언할거에요 -> HP 텍스트를 갱신하는 UpdateHPText를 { if (hpText == null || _playerHealth == null || _playerStats == null) return; // 조건이 맞으면 중단할거에요 -> 필수 참조가 없으면 float current = _playerHealth.CurrentHP; // 값을 가져올거에요 -> 현재 체력을 float max = _playerStats.MaxHealth; // 값을 가져올거에요 -> 최대 체력을 hpText.text = $"{current:F0} / {max:F0}"; // 텍스트를 설정할거에요 -> "현재 / 최대" 형식으로 } /// /// 이벤트 없이 직접 UI를 갱신 (Start, 수동 호출용) /// private void UpdateUI() // 함수를 선언할거에요 -> 전체 UI 갱신을 { if (_playerHealth == null || _playerStats == null) return; // 조건이 맞으면 중단할거에요 -> 참조가 없으면 float max = _playerStats.MaxHealth; // 값을 가져올거에요 -> 최대 체력을 float current = _playerHealth.CurrentHP; // 값을 가져올거에요 -> 현재 체력을 float ratio = (max > 0) ? current / max : 0f; // 비율을 계산할거에요 -> 현재/최대로 if (hpFilledImage != null) // 조건이 맞으면 실행할거에요 -> Fill 이미지가 있다면 { hpFilledImage.fillAmount = Mathf.Clamp01(ratio); // 값을 설정할거에요 -> Fill Amount를 } UpdateHPText(); // 실행할거에요 -> 텍스트 갱신을 } }