using System; using Cielonos.MainGame; using SLSUtilities.UI; using TMPro; using UnityEngine; using DG.Tweening; namespace Cielonos.MainGame.UI { public class PassionSystemUIArea : UIElementBase { [Header("UI References")] public TMP_Text levelText; public TMP_Text percentageText; private PassionSystem _passionSystem; // 缓存原始位置以解决高频动画重合重叠时的坐标偏移累积问题 private Vector3 _levelTextOrigPos; private Vector3 _percentTextOrigPos; private void Start() { // 获取单例系统,确保如果未找到直接抛出异常 _passionSystem = CombatManager.GetCombatSystem(); _passionSystem.OnLevelChanged += OnLevelChanged; _passionSystem.OnPercentChanged += OnPercentChanged; _passionSystem.OnPassionIncreased += OnPassionIncreased; _passionSystem.OnPassionDecreased += OnPassionDecreased; // 缓存初始相对坐标 _levelTextOrigPos = levelText.transform.localPosition; _percentTextOrigPos = percentageText.transform.localPosition; // 设定初始显示 UpdateDisplay(_passionSystem.levelIndex, _passionSystem.percent); } private void OnDestroy() { if (_passionSystem != null) { _passionSystem.OnLevelChanged -= OnLevelChanged; _passionSystem.OnPercentChanged -= OnPercentChanged; _passionSystem.OnPassionIncreased -= OnPassionIncreased; _passionSystem.OnPassionDecreased -= OnPassionDecreased; } } private void OnLevelChanged(int oldLevel, int newLevel) { UpdateDisplay(newLevel, _passionSystem.percent); if (newLevel > oldLevel) { PlayLevelUpAnimation(); } else if (newLevel < oldLevel) { PlayLevelDownAnimation(); } } private void OnPercentChanged(float percent) { UpdateDisplay(_passionSystem.levelIndex, percent); } private void OnPassionIncreased(float amount, bool applyMultipliers) { PlayPercentIncreaseAnimation(); } private void OnPassionDecreased(float amount, bool applyMultipliers) { // 只有当受击等 reactive 负面反应触发减少时才播放受击抖动 if (applyMultipliers) { PlayPercentDecreaseAnimation(); } } private void UpdateDisplay(int currentLevel, float currentPercent) { var levelInfo = _passionSystem.passionLevels[currentLevel]; // 更新文本与颜色,无防御性 Null 校验以保证能抛出显式异常 levelText.text = levelInfo.levelType.ToString(); levelText.color = levelInfo.levelColor; percentageText.text = $"{Mathf.FloorToInt(currentPercent)}%"; percentageText.color = levelInfo.levelColor; } // ========================================== // DOTween 动画及重叠冲突重置逻辑 // ========================================== private void PlayLevelUpAnimation() { // 杀死该 Transform 上的全部活动动画,并立即恢复初值状态,彻底解决高频触发下的形变累积问题 levelText.transform.DOKill(); levelText.transform.localScale = Vector3.one; levelText.transform.localPosition = _levelTextOrigPos; // 升级:弹性膨胀反馈,显式调用 .Play() 以确保播放 levelText.transform.DOPunchScale(new Vector3(0.5f, 0.5f, 0f), 0.45f, 10, 1f).Play(); } private void PlayLevelDownAnimation() { levelText.transform.DOKill(); levelText.transform.localScale = Vector3.one; levelText.transform.localPosition = _levelTextOrigPos; // 降级:左右剧烈晃动,以及缩水回弹,显式调用 .Play() levelText.transform.DOShakePosition(0.4f, new Vector3(10f, 0f, 0f), 20, 90f).Play(); levelText.transform.DOPunchScale(new Vector3(-0.25f, -0.25f, 0f), 0.35f, 5, 0.5f).Play(); } private void PlayPercentIncreaseAnimation() { percentageText.transform.DOKill(); percentageText.transform.localScale = Vector3.one; percentageText.transform.localPosition = _percentTextOrigPos; // 增加百分比:轻微向上跳动和快速缩放弹跳,显式调用 .Play() percentageText.transform.DOPunchScale(new Vector3(0.18f, 0.18f, 0f), 0.15f, 6, 0.5f).Play(); } private void PlayPercentDecreaseAnimation() { percentageText.transform.DOKill(); percentageText.transform.localScale = Vector3.one; percentageText.transform.localPosition = _percentTextOrigPos; // 受击损失百分比:上下震颤摇晃,以及明显的凹陷缩水,显式调用 .Play() percentageText.transform.DOShakePosition(0.35f, new Vector3(6f, 4f, 0f), 22).Play(); percentageText.transform.DOPunchScale(new Vector3(-0.2f, -0.2f, 0f), 0.25f, 5, 0.5f).Play(); } } }