148 lines
4.8 KiB
C#
148 lines
4.8 KiB
C#
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<ResAddEvent>().Subscribe(OnResAddEvent).AddTo(this);
|
||
var data = GContext.container.Resolve<EventPartnerStatueTokenExchangeData>();
|
||
if (data == null)
|
||
{
|
||
gameObject.SetActive(false);
|
||
return;
|
||
}
|
||
SetData(data);
|
||
}
|
||
|
||
// private void OnEnable()
|
||
// {
|
||
// var data = GContext.container.Resolve<EventPartnerStatueTokenExchangeData>();
|
||
// if (data == null)
|
||
// return;
|
||
// TryConsumePendingScoreUi(data);
|
||
// }
|
||
|
||
private void OnResAddEvent(ResAddEvent e)
|
||
{
|
||
if (e.Type != 15 || e.SubType != 4)
|
||
return;
|
||
var data = GContext.container.Resolve<EventPartnerStatueTokenExchangeData>();
|
||
if (data == null)
|
||
{
|
||
gameObject.SetActive(false);
|
||
return;
|
||
}
|
||
TryConsumePendingScoreUi(data);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 逻辑已加分且有待播的 UI 表现时播放动画;否则将 UI 与数据对齐。
|
||
/// </summary>
|
||
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<IEventPartnerTokenExchangeContext>();
|
||
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<EventPartnerStatueTokenExchangeData>();
|
||
if (latest != null)
|
||
SetData(latest);
|
||
}
|
||
}
|
||
|
||
private IEnumerator PlayProgressAnimation(float startFill, int oldTicketCount, int tokenToGive, float progressRatio)
|
||
{
|
||
var context = GContext.container.Resolve<IEventPartnerTokenExchangeContext>();
|
||
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
|
||
|
||
}
|