using UnityEngine; public class DamageIndicatorHandler : MonoBehaviour, IOwnedComponent { struct DmgIndicatorProperty { public float fontSize; public Color color; } static readonly DmgIndicatorProperty _normalDmgIndicatorProp = new DmgIndicatorProperty { fontSize = 24f, color = new Color(1f, 1f, 1f) }; static readonly DmgIndicatorProperty _criticalDmgIndicatorProp = new DmgIndicatorProperty { fontSize = 32f, color = new Color(1f, 56f / 255f, 0f) }; Camera _mainCamera; Camera _uiCamera; RectTransform _indicatorRoot; [SerializeField] Transform spawnPosition; [SerializeField] DamageIndicatorText indicatorPrefab; public Character Owner { get; private set; } DynamicMonoObjectPool indicatorPool; public void Initialize(Character owner) { Owner = owner; Owner.OnDamaged += OnDamaged; _mainCamera = Camera.main; _uiCamera = GameObject.FindGameObjectWithTag(GameProperty.Instance.UICameraTag).GetComponent(); _indicatorRoot = GameObject.FindGameObjectWithTag(GameProperty.Instance.DamageIndicatorRootTag).GetComponent(); indicatorPool = new(); indicatorPool.Initialize( InstantiateIndicator, DestroyIndicator, (obj) => { obj.Hide(); }, (obj) => { }, 5); } private DamageIndicatorText InstantiateIndicator() { var indicator = Instantiate(indicatorPrefab, _indicatorRoot); indicator.OnComplete += indicatorPool.Return; return indicator; } private void DestroyIndicator(DamageIndicatorText indicator) { if (indicator == null || indicator.gameObject == null) return; Destroy(indicator.gameObject); } private void OnDamaged(Character _, Damage damage) { var indicator = indicatorPool.Get(); if (damage.isCritical) indicator.SetText(FormatString.BigIntString1(damage.value), _criticalDmgIndicatorProp.fontSize, _criticalDmgIndicatorProp.color); else indicator.SetText(FormatString.BigIntString1(damage.value), _normalDmgIndicatorProp.fontSize, _normalDmgIndicatorProp.color); var screenPos = _mainCamera.WorldToScreenPoint(spawnPosition.position); RectTransformUtility.ScreenPointToLocalPointInRectangle(_indicatorRoot, screenPos, _uiCamera, out Vector2 localPos); indicator.transform.localPosition = localPos; indicator.Show(); } private void OnDestroy() { if (Owner == null) return; Owner.OnDamaged -= OnDamaged; indicatorPool.Dispose(); } }