using Framework; using System; using Gameplay; using TMPro; using UnityEngine; using UnityEngine.UI; /// /// 控制高级账户剩余天数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 = "普通账号"; [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.IsActivated) { gameObject.transform.localScale = Vector3.one; CancelInvoke(nameof(UpdateDaily)); icon.sprite = expiredSprite; remainingDaysText.text = expiredText; remainingDaysText.color = expiredColor; DebugUtil.LogError("此处需要本地化"); 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; //时间为0,则显示为过期 if (remainingSeconds <= 0) { icon.sprite = expiredSprite; remainingDaysText.text = expiredText; remainingDaysText.color = expiredColor; DebugUtil.LogError("此处需要本地化"); } TimeSpan remainingTime = TimeSpan.FromSeconds(remainingSeconds); //向下取整的天数 int realDays = (int)remainingTime.TotalDays; // 向上取整,例如剩余1.1天,也算作2天。如果小于0则为0。 int days = Math.Max(0, (int)Math.Ceiling(remainingTime.TotalDays)); if (realDays >0) { remainingDaysText.text = StringManager.Instance.GetLocalizeTextByKeyAndParams("PremiumPerk_Remain_Day", days); if (icon != null && normalSprite != null) { icon.sprite = normalSprite; remainingDaysText.color = normalColor; } return; } int realHours = remainingTime.Hours; int hours = Math.Max(0, (int)Math.Ceiling(remainingTime.TotalHours)); if(realHours>0) { remainingDaysText.text = StringManager.Instance.GetLocalizeTextByKeyAndParams("PremiumPerk_Remain_Hour", hours); if (icon != null && normalSprite != null) { icon.sprite = normalSprite; remainingDaysText.color = normalColor; } return; } //不足一小时 int realSeconds = remainingTime.Seconds; if (realSeconds > 0) { remainingDaysText.text = StringManager.Instance.GetLocalizeTextByKeyAndParams("PremiumPerk_Remain_Hour", 1); if (icon != null && normalSprite != null) { icon.sprite = normalSprite; remainingDaysText.color = normalColor; } } } [Sirenix.OdinInspector.Button] private void TestUpdateUI() { TimeSpan testTime = new TimeSpan(testDays, testHours, testMinutes, 0); UpdateRemainingDays((long)testTime.TotalSeconds); Debug.Log($"测试更新: {testDays}天 {testHours}时 {testMinutes}分"); } }