using UnityEngine; using UnityEngine.UI; using TMPro; namespace Northbound { /// /// 건물 위에 표시되는 체력바 /// public class BuildingHealthBar : MonoBehaviour { [Header("UI References")] public Image fillImage; public TextMeshProUGUI healthText; public GameObject barContainer; [Header("Settings")] public float heightOffset = 3f; public bool hideWhenFull = true; public float hideDelay = 3f; [Header("Colors")] public Color fullHealthColor = Color.green; public Color mediumHealthColor = Color.yellow; public Color lowHealthColor = Color.red; public float mediumHealthThreshold = 0.6f; public float lowHealthThreshold = 0.3f; private Building _building; private Camera _mainCamera; private float _lastDamageTime; private Canvas _canvas; private void Awake() { // Canvas 설정 _canvas = GetComponent(); if (_canvas == null) { _canvas = gameObject.AddComponent(); } _canvas.renderMode = RenderMode.WorldSpace; // Canvas Scaler 설정 var scaler = GetComponent(); if (scaler == null) { scaler = gameObject.AddComponent(); } scaler.dynamicPixelsPerUnit = 10f; } private void Start() { _mainCamera = Camera.main; } public void Initialize(Building building) { _building = building; transform.localPosition = Vector3.up * heightOffset; } public void UpdateHealth(int currentHealth, int maxHealth) { if (fillImage != null) { float healthPercentage = maxHealth > 0 ? (float)currentHealth / maxHealth : 0f; fillImage.fillAmount = healthPercentage; // 체력에 따른 색상 변경 fillImage.color = GetHealthColor(healthPercentage); } if (healthText != null) { healthText.text = $"{currentHealth}/{maxHealth}"; } // 체력바 표시/숨김 if (barContainer != null) { _lastDamageTime = Time.time; barContainer.SetActive(true); } } private void Update() { // 카메라를 향하도록 회전 if (_mainCamera != null) { transform.rotation = Quaternion.LookRotation(transform.position - _mainCamera.transform.position); } // 체력이 가득 차면 숨김 if (hideWhenFull && barContainer != null && _building != null) { float healthPercentage = _building.GetHealthPercentage(); if (healthPercentage >= 1f && Time.time - _lastDamageTime > hideDelay) { barContainer.SetActive(false); } } } private Color GetHealthColor(float healthPercentage) { if (healthPercentage <= lowHealthThreshold) return lowHealthColor; else if (healthPercentage <= mediumHealthThreshold) return mediumHealthColor; else return fullHealthColor; } } }