using System; using UnityEngine; using TMPro; using DG.Tweening; using XUI; public class GameEndPanel : UIBehaviour { public TMP_Text scoreText; public GameObject[] stars; [Header("Star Animation")] [NonSerialized] public float starDelay = 1f; public float starScaleUpTime = 0.5f; public float starScaleDownTime = 0.3f; public float starMaxScale = 1.4f; [Header("Score Animation")] public float scoreAnimDuration = 2f; public static void Show(params object[] args) { WorldUIManager.Ins.Cover("UI/GameEndPanel", false, args); } public override void OnUIShow(params object[] args) { base.OnUIShow(args); int finalScore = GameInit.Ins.self.Score; InitStars(); PlayScoreAnimation(finalScore); PlayStarSequence(3); } #region Score Animation private void PlayScoreAnimation(int targetScore) { scoreText.text = "0"; DOTween.To( () => 0, value => scoreText.text = value.ToString("N0"), targetScore, scoreAnimDuration ).SetEase(Ease.OutCubic); } #endregion #region Star Animation private void InitStars() { if (stars == null) return; foreach (var star in stars) { if (star == null) continue; star.SetActive(false); star.transform.localScale = Vector3.zero; } } private void PlayStarSequence(int starCount) { starCount = Mathf.Clamp(starCount, 0, stars.Length); Sequence seq = DOTween.Sequence(); for (int i = 0; i < starCount; i++) { int index = i; seq.AppendCallback(() => PlaySingleStar(stars[index])); seq.AppendInterval(starDelay); } } private void PlaySingleStar(GameObject star) { if (star == null) return; star.SetActive(true); star.transform.localScale = Vector3.zero; Sequence starSeq = DOTween.Sequence(); // 放大(带弹性) starSeq.Append( star.transform.DOScale(starMaxScale, starScaleUpTime) .SetEase(Ease.OutBack) ); // 回弹到 1 starSeq.Append( star.transform.DOScale(1f, starScaleDownTime) .SetEase(Ease.OutBounce) ); } #endregion }