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; public float initialShowDuration = 2f; // 건설 완료 시 체력바 표시 시간 [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 _lastShowTime; private Canvas _canvas; private bool _initialized = false; 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; // 건설 완료 시 체력바 표시 ShowBar(initialShowDuration); _initialized = true; } /// /// 체력바를 지정된 시간 동안 표시 /// public void ShowBar(float duration = 0f) { if (barContainer != null) { barContainer.SetActive(true); _lastShowTime = Time.time; // duration이 0보다 크면 그 시간 동안만 표시 if (duration > 0) { _lastShowTime = Time.time + duration - hideDelay; } } } 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}"; } // 체력 변경 시 체력바 표시 ShowBar(); } private void Update() { // 카메라를 향하도록 회전 if (_mainCamera != null) { transform.rotation = Quaternion.LookRotation(transform.position - _mainCamera.transform.position); } // 체력이 가득 차면 숨김 if (hideWhenFull && barContainer != null && _building != null && _initialized) { float healthPercentage = _building.GetHealthPercentage(); if (healthPercentage >= 1f && Time.time - _lastShowTime > hideDelay) { barContainer.SetActive(false); } } } private Color GetHealthColor(float healthPercentage) { if (healthPercentage <= lowHealthThreshold) return lowHealthColor; else if (healthPercentage <= mediumHealthThreshold) return mediumHealthColor; else return fullHealthColor; } } }