using Framework; using System; using Gameplay; using TMPro; using UnityEngine; using UnityEngine.UI; using Gameplay.Utils; /// /// 控制高级账户剩余天数UI的显示和更新 /// public class PremiumRemainingDaysUI : MonoBehaviour { [Header("显示剩余天数的文本组件")] [SerializeField] private TextMeshProUGUI remainingDaysText; [Header("Image组件")] [SerializeField] private Image icon; [Header("激活状态")] [SerializeField] private Sprite normalSprite; [SerializeField] private Color normalColor; [Header("过期状态显示")] [SerializeField] private Sprite expiredSprite; [SerializeField] private string expiredText = "PremiumPerk_Common"; [SerializeField] private Color expiredColor; [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; private void OnEnable() { EventManager.Instance.Register(EventManager.EventName.PremiumStatusRefresh, OnPremiumStatusChanged); EventManager.Instance.Send(EventManager.EventName.RequestPremiumStatus); } private void OnDisable() { EventManager.Instance.Unregister(EventManager.EventName.PremiumStatusRefresh, OnPremiumStatusChanged); CancelInvoke(nameof(UpdateDaily)); } private void OnPremiumStatusChanged(PremiumStatusChangedEvent eventData) { if(eventData.OnlyPvpStatus) return; if(remainingDaysText==null) remainingDaysText = gameObject.transform.Find("Text_Day").GetComponent(); if(icon==null) icon = gameObject.transform.Find("Image").GetComponent(); if(!eventData.IsActivated) { gameObject.transform.localScale = Vector3.one; CancelInvoke(nameof(UpdateDaily)); icon.sprite = expiredSprite; remainingDaysText.text = StringManager.Instance.GetLocalizeTextByKey(expiredText); remainingDaysText.color = expiredColor; return; } if (eventData.IsActivated) { gameObject.transform.localScale = Vector3.one; UpdateRemainingDays(eventData.RemainingSeconds); // 为了防止重复调用,先取消之前的 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); } } /// /// 每日自动更新的函数 /// private void UpdateDaily() { // 重新请求一下最新状态,保证数据准确性,并重新安排下一次更新 EventManager.Instance.Send(EventManager.EventName.RequestPremiumStatus); } /// /// 根据剩余时间(秒)更新UI /// private void UpdateRemainingDays(long remainingSeconds) { if (remainingDaysText == null) return; #region 时间小于0 //时间为0,则显示为过期 if (remainingSeconds <= 0) { icon.sprite = expiredSprite; remainingDaysText.text = StringManager.Instance.GetLocalizeTextByKey(expiredText); remainingDaysText.color = expiredColor; return; } #endregion #region 时间大于0 TimeSpan remainingTime = TimeSpan.FromSeconds(remainingSeconds); //向下取整的小时数 var realHours = remainingTime.TotalHours; if (realHours>23) { // 向上取整,例如剩余1.1天,也算作2天。如果小于0则为0。 int days = Math.Max(0, (int)Math.Ceiling(remainingTime.TotalDays)); remainingDaysText.text = StringManager.Instance.GetLocalizeTextByKeyAndParams("PremiumPerk_Remain_Day", days); if (icon != null && normalSprite != null) { icon.sprite = normalSprite; remainingDaysText.color = normalColor; } } else { int hours = Math.Max(0, (int)Math.Ceiling(remainingTime.TotalHours)); remainingDaysText.text = StringManager.Instance.GetLocalizeTextByKeyAndParams("PremiumPerk_Remain_Hour", hours); if (icon != null && normalSprite != null) { icon.sprite = normalSprite; remainingDaysText.color = normalColor; } } #endregion } [Sirenix.OdinInspector.Button] private void TestUpdateUI() { TimeSpan testTime = new TimeSpan(testDays, testHours, testMinutes, 0); UpdateRemainingDays((long)testTime.TotalSeconds); Debug.Log($"测试更新: {testDays}天 {testHours}时 {testMinutes}分"); } }