2026-01-14 12:13:44 +08:00
|
|
|
|
using Framework;
|
|
|
|
|
|
using System;
|
2026-01-23 13:42:28 +08:00
|
|
|
|
using Gameplay;
|
2026-01-14 12:13:44 +08:00
|
|
|
|
using TMPro;
|
|
|
|
|
|
using UnityEngine;
|
2026-01-22 19:40:24 +08:00
|
|
|
|
using UnityEngine.UI;
|
2026-01-27 20:00:18 +08:00
|
|
|
|
using Gameplay.Utils;
|
2026-01-14 12:13:44 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 控制高级账户剩余天数UI的显示和更新
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class PremiumRemainingDaysUI : MonoBehaviour
|
|
|
|
|
|
{
|
2026-01-22 19:40:24 +08:00
|
|
|
|
[Header("显示剩余天数的文本组件")] [SerializeField]
|
|
|
|
|
|
private TextMeshProUGUI remainingDaysText;
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Image组件")]
|
2026-01-23 13:42:28 +08:00
|
|
|
|
[SerializeField] private Image icon;
|
2026-01-22 19:40:24 +08:00
|
|
|
|
|
2026-01-23 13:42:28 +08:00
|
|
|
|
[Header("激活状态")]
|
2026-01-22 19:40:24 +08:00
|
|
|
|
[SerializeField] private Sprite normalSprite;
|
2026-01-23 13:42:28 +08:00
|
|
|
|
[SerializeField] private Color normalColor;
|
|
|
|
|
|
|
2026-01-22 19:40:24 +08:00
|
|
|
|
[Header("过期状态显示")]
|
|
|
|
|
|
[SerializeField] private Sprite expiredSprite;
|
2026-01-27 20:00:18 +08:00
|
|
|
|
[SerializeField] private string expiredText = "PremiumPerk_Common";
|
2026-01-23 13:42:28 +08:00
|
|
|
|
[SerializeField] private Color expiredColor;
|
2026-01-22 19:40:24 +08:00
|
|
|
|
|
|
|
|
|
|
[Header("测试参数")]
|
|
|
|
|
|
[SerializeField, Range(0, 365)] private int testDays = 5;
|
|
|
|
|
|
[SerializeField, Range(0, 24)] private int testHours = 12;
|
|
|
|
|
|
[SerializeField, Range(0, 60)] private int testMinutes = 30;
|
2026-01-14 12:13:44 +08:00
|
|
|
|
|
|
|
|
|
|
private void OnEnable()
|
|
|
|
|
|
{
|
2026-01-22 19:40:24 +08:00
|
|
|
|
EventManager.Instance.Register<PremiumStatusChangedEvent>(EventManager.EventName.PremiumStatusRefresh,
|
|
|
|
|
|
OnPremiumStatusChanged);
|
2026-01-14 12:13:44 +08:00
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.RequestPremiumStatus);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnDisable()
|
|
|
|
|
|
{
|
2026-01-22 19:40:24 +08:00
|
|
|
|
EventManager.Instance.Unregister<PremiumStatusChangedEvent>(EventManager.EventName.PremiumStatusRefresh,
|
|
|
|
|
|
OnPremiumStatusChanged);
|
2026-01-14 12:13:44 +08:00
|
|
|
|
CancelInvoke(nameof(UpdateDaily));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnPremiumStatusChanged(PremiumStatusChangedEvent eventData)
|
|
|
|
|
|
{
|
2026-06-03 15:24:47 +08:00
|
|
|
|
if(eventData.OnlyPvpStatus)
|
|
|
|
|
|
return;
|
2026-01-28 12:53:21 +08:00
|
|
|
|
if(remainingDaysText==null) remainingDaysText = gameObject.transform.Find("Text_Day").GetComponent<TextMeshProUGUI>();
|
|
|
|
|
|
if(icon==null) icon = gameObject.transform.Find("Image").GetComponent<Image>();
|
|
|
|
|
|
|
2026-01-23 13:42:28 +08:00
|
|
|
|
if(!eventData.IsActivated)
|
|
|
|
|
|
{
|
|
|
|
|
|
gameObject.transform.localScale = Vector3.one;
|
|
|
|
|
|
CancelInvoke(nameof(UpdateDaily));
|
|
|
|
|
|
|
|
|
|
|
|
icon.sprite = expiredSprite;
|
2026-01-27 20:00:18 +08:00
|
|
|
|
remainingDaysText.text = StringManager.Instance.GetLocalizeTextByKey(expiredText);
|
2026-01-23 13:42:28 +08:00
|
|
|
|
remainingDaysText.color = expiredColor;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (eventData.IsActivated)
|
2026-01-14 12:13:44 +08:00
|
|
|
|
{
|
|
|
|
|
|
gameObject.transform.localScale = Vector3.one;
|
2026-01-22 19:40:24 +08:00
|
|
|
|
UpdateRemainingDays(eventData.RemainingSeconds);
|
2026-01-14 12:13:44 +08:00
|
|
|
|
|
|
|
|
|
|
// 为了防止重复调用,先取消之前的
|
|
|
|
|
|
CancelInvoke(nameof(UpdateDaily));
|
|
|
|
|
|
|
|
|
|
|
|
// 安排一个每日更新任务,在第二天的零点过1秒后触发
|
|
|
|
|
|
DateTime now = DateTime.Now;
|
|
|
|
|
|
DateTime tomorrow = now.AddDays(1).Date;
|
|
|
|
|
|
double secondsUntilTomorrow = (tomorrow - now).TotalSeconds;
|
|
|
|
|
|
Invoke(nameof(UpdateDaily), (float)secondsUntilTomorrow + 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 每日自动更新的函数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void UpdateDaily()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 重新请求一下最新状态,保证数据准确性,并重新安排下一次更新
|
|
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.RequestPremiumStatus);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-01-16 19:35:52 +08:00
|
|
|
|
/// 根据剩余时间(秒)更新UI
|
2026-01-14 12:13:44 +08:00
|
|
|
|
/// </summary>
|
2026-01-16 19:35:52 +08:00
|
|
|
|
private void UpdateRemainingDays(long remainingSeconds)
|
2026-01-14 12:13:44 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (remainingDaysText == null) return;
|
2026-01-30 15:36:38 +08:00
|
|
|
|
|
|
|
|
|
|
#region 时间小于0
|
2026-01-23 13:42:28 +08:00
|
|
|
|
//时间为0,则显示为过期
|
|
|
|
|
|
if (remainingSeconds <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
icon.sprite = expiredSprite;
|
2026-01-27 20:00:18 +08:00
|
|
|
|
remainingDaysText.text = StringManager.Instance.GetLocalizeTextByKey(expiredText);
|
2026-01-23 13:42:28 +08:00
|
|
|
|
remainingDaysText.color = expiredColor;
|
2026-01-27 20:00:18 +08:00
|
|
|
|
return;
|
2026-01-23 13:42:28 +08:00
|
|
|
|
}
|
2026-01-30 15:36:38 +08:00
|
|
|
|
#endregion
|
2026-01-14 12:13:44 +08:00
|
|
|
|
|
2026-01-30 15:36:38 +08:00
|
|
|
|
#region 时间大于0
|
2026-01-16 19:35:52 +08:00
|
|
|
|
TimeSpan remainingTime = TimeSpan.FromSeconds(remainingSeconds);
|
2026-01-23 13:42:28 +08:00
|
|
|
|
|
2026-01-30 15:36:38 +08:00
|
|
|
|
//向下取整的小时数
|
|
|
|
|
|
var realHours = remainingTime.TotalHours;
|
|
|
|
|
|
|
|
|
|
|
|
if (realHours>23)
|
2026-01-22 19:40:24 +08:00
|
|
|
|
{
|
2026-01-30 15:36:38 +08:00
|
|
|
|
// 向上取整,例如剩余1.1天,也算作2天。如果小于0则为0。
|
|
|
|
|
|
int days = Math.Max(0, (int)Math.Ceiling(remainingTime.TotalDays));
|
|
|
|
|
|
|
2026-01-22 19:40:24 +08:00
|
|
|
|
remainingDaysText.text =
|
|
|
|
|
|
StringManager.Instance.GetLocalizeTextByKeyAndParams("PremiumPerk_Remain_Day", days);
|
2026-01-23 13:42:28 +08:00
|
|
|
|
if (icon != null && normalSprite != null)
|
2026-01-22 19:40:24 +08:00
|
|
|
|
{
|
2026-01-23 13:42:28 +08:00
|
|
|
|
icon.sprite = normalSprite;
|
|
|
|
|
|
remainingDaysText.color = normalColor;
|
2026-01-22 19:40:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-30 15:36:38 +08:00
|
|
|
|
else
|
2026-01-22 19:40:24 +08:00
|
|
|
|
{
|
2026-01-30 15:36:38 +08:00
|
|
|
|
int hours = Math.Max(0, (int)Math.Ceiling(remainingTime.TotalHours));
|
2026-01-22 19:40:24 +08:00
|
|
|
|
remainingDaysText.text =
|
|
|
|
|
|
StringManager.Instance.GetLocalizeTextByKeyAndParams("PremiumPerk_Remain_Hour", hours);
|
2026-01-23 13:42:28 +08:00
|
|
|
|
if (icon != null && normalSprite != null)
|
2026-01-22 19:40:24 +08:00
|
|
|
|
{
|
2026-01-23 13:42:28 +08:00
|
|
|
|
icon.sprite = normalSprite;
|
|
|
|
|
|
remainingDaysText.color = normalColor;
|
2026-01-22 19:40:24 +08:00
|
|
|
|
}
|
2026-01-14 18:37:36 +08:00
|
|
|
|
}
|
2026-01-30 15:36:38 +08:00
|
|
|
|
#endregion
|
2026-01-14 12:13:44 +08:00
|
|
|
|
}
|
2026-01-22 19:40:24 +08:00
|
|
|
|
|
|
|
|
|
|
[Sirenix.OdinInspector.Button]
|
|
|
|
|
|
private void TestUpdateUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
TimeSpan testTime = new TimeSpan(testDays, testHours, testMinutes, 0);
|
|
|
|
|
|
UpdateRemainingDays((long)testTime.TotalSeconds);
|
|
|
|
|
|
Debug.Log($"测试更新: {testDays}天 {testHours}时 {testMinutes}分");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|