using UnityEngine; using UnityEngine.UI; using asap.core; using System.Collections; using DG.Tweening; using TMPro; using UniRx; public class EventPartnerStatueTokenExchangeManager : MonoBehaviour { #region UIElements [SerializeField] private Image bar; [SerializeField] private TMP_Text textPercentage; #endregion #region Params [SerializeField] private float progressAnimationDuration = 0.3f; [SerializeField] private float homePanelAnimationDelay = 2f; #endregion private Coroutine _progressAnimationCoroutine = null; private void Start() { // TryConsumePendingScoreUi(data); GContext.OnEvent().Subscribe(OnResAddEvent).AddTo(this); var data = GContext.container.Resolve(); if (data == null) { gameObject.SetActive(false); return; } SetData(data); } // private void OnEnable() // { // var data = GContext.container.Resolve(); // if (data == null) // return; // TryConsumePendingScoreUi(data); // } private void OnResAddEvent(ResAddEvent e) { if (e.Type != 15 || e.SubType != 4) return; var data = GContext.container.Resolve(); if (data == null) { gameObject.SetActive(false); return; } TryConsumePendingScoreUi(data); } /// /// 逻辑已加分且有待播的 UI 表现时播放动画;否则将 UI 与数据对齐。 /// private void TryConsumePendingScoreUi(EventPartnerStatueTokenExchangeData data) { if (!isActiveAndEnabled) return; if (_progressAnimationCoroutine != null) return; if (data.PendingScoreUiCount > 0) _progressAnimationCoroutine = StartCoroutine(ProcessPendingScoreUiQueue(data)); else SetData(data); } #region Data storage public void SetData(EventPartnerStatueTokenExchangeData data) { var context = GContext.container.Resolve(); if (context == null) return; var percentage = data.GetCurrentPercentage(); bar.fillAmount = percentage; textPercentage.text = percentage.ToPercentageString(); if (data.PendingScoreUiCount == 0) { RedPointManager.Instance.SetRedPointState(context.RedPointKey, context.TicketCount > 0, context.TicketCount); } else { var tokenCountForNow = context.TicketCount - data.PendingScoreUiTokenToGive; RedPointManager.Instance.SetRedPointState(context.RedPointKey, tokenCountForNow > 0, tokenCountForNow); } } #endregion #region Display logic private IEnumerator ProcessPendingScoreUiQueue(EventPartnerStatueTokenExchangeData data) { try { // Peek → 播完再 Dequeue,避免 Manager 中途销毁时已出队但未播完的条目永久丢失 while (data.PendingScoreUiCount > 0) { if (!data.TryPeekPendingScoreUi(out var item)) break; yield return PlayProgressAnimation(item.StartFill, item.OldTicketCount, item.TokenToGive, item.EndProgressRatio); data.DequeueConsumedPendingScoreUi(); } } finally { _progressAnimationCoroutine = null; var latest = GContext.container.Resolve(); if (latest != null) SetData(latest); } } private IEnumerator PlayProgressAnimation(float startFill, int oldTicketCount, int tokenToGive, float progressRatio) { var context = GContext.container.Resolve(); bar.fillAmount = startFill; textPercentage.text = bar.fillAmount.ToPercentageString(); while (tokenToGive > 0) { tokenToGive--; yield return bar.DOFillAmount(1f, progressAnimationDuration).OnUpdate(() => { textPercentage.text = bar.fillAmount.ToPercentageString(); }).WaitForCompletion(); GContext.Publish(new Game.EventUISound("audio_ui_reward_icon_3")); if (context != null) RedPointManager.Instance.SetRedPointState(context.RedPointKey, true, ++oldTicketCount); bar.fillAmount = 0f; yield return null; } yield return bar.DOFillAmount(progressRatio, progressAnimationDuration) .OnUpdate(() => { textPercentage.text = bar.fillAmount.ToPercentageString(); }) .WaitForCompletion(); } #endregion }