using System; using DG.Tweening; using TMPro; using UnityEngine; namespace SepCore.DamageText { public class DamageTextItem : MonoBehaviour { private const float RiseDistance = 80f; private const float RiseDuration = 0.55f; private const float FadeDelay = 0.2f; private const float FadeDuration = 0.35f; private static readonly Color NormalColor = new Color(1f, 0.32f, 0.23f, 1f); private static readonly Color CritColor = new Color(1f, 0.85f, 0.15f, 1f); private static readonly Color DodgeColor = new Color(0.75f, 0.75f, 0.75f, 1f); [SerializeField] private RectTransform _cachedTransform = null; [SerializeField] private CanvasGroup _canvasGroup = null; [SerializeField] private TMP_Text _text = null; private Sequence _sequence; private Action _onComplete; public void Show(Vector3 worldPosition, int damage, bool isCrit, bool isDodge, Canvas canvas, Action onComplete) { _onComplete = onComplete; gameObject.SetActive(true); KillSequence(); _canvasGroup.alpha = 1f; _cachedTransform.localScale = Vector3.one; Vector3 punchScale; if (isDodge) { _text.color = DodgeColor; _text.text = "MISS"; punchScale = new Vector3(0.1f, 0.1f, 0f); } else if (isCrit) { _text.color = CritColor; _text.text = damage.ToString() + "!"; _cachedTransform.localScale = new Vector3(1.3f, 1.3f, 1f); punchScale = new Vector3(0.35f, 0.35f, 0f); } else { _text.color = NormalColor; _text.text = damage.ToString(); punchScale = new Vector3(0.15f, 0.15f, 0f); } Vector3 screenPos = GameEntry.Scene.MainCamera.WorldToScreenPoint(worldPosition); RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)canvas.transform, screenPos, canvas.worldCamera, out Vector2 localPos); localPos.x += UnityEngine.Random.Range(-24f, 24f); _cachedTransform.anchoredPosition = localPos; _sequence = DOTween.Sequence(); _sequence.Append(_cachedTransform.DOAnchorPosY(localPos.y + RiseDistance, RiseDuration) .SetEase(Ease.OutQuad)); _sequence.Join(_cachedTransform.DOPunchScale(punchScale, 0.18f, 6, 0.75f)); _sequence.Join(_canvasGroup.DOFade(0f, FadeDuration).SetDelay(FadeDelay)); _sequence.OnComplete(() => _onComplete(this)); } public void Show(Vector3 worldPosition, int damage, Canvas canvas, Action onComplete) { Show(worldPosition, damage, false, false, canvas, onComplete); } public void ResetItem() { KillSequence(); _onComplete = null; _canvasGroup.alpha = 1f; _text.text = string.Empty; gameObject.SetActive(false); } private void OnDestroy() { KillSequence(); } private void KillSequence() { if (_sequence == null) return; _sequence.Kill(); _sequence = null; } } }