Unity开发--单机游戏中时间循环管理

在单机游戏中,前端通常要做时间循环相关控制。如:某个活动固定周二开启、固定每月某个时间开启、登录后每隔4天开启(首购礼包)、注册后按照注册日期每隔5天开启等,这通常需要一个时间循环管理器。
配置表导出格式:

public partial class TimeCycleConfig{
    
    
	/// <summary>
	/// 循环ID
	/// </summary>
	public int Id;

	/// <summary>
	/// 当前循环时间描述
	/// </summary>
	public string Disc;

	/// <summary>
	/// 日期规则
	/// 1:按照注册天数计算
	/// 2:按照登录天数计算
	/// 3:按照每周计算
	/// 4:按照每月计算
	/// </summary>
	public int DateRule;

	/// <summary>
	/// 循环周期(天)
	/// 周、月计算时默认0
	/// </summary>
	public int CyclePeriod;

	/// <summary>
	/// 在循环内第几个小时开始(单位:H)
	/// </summary>
	public int StartTime;

	/// <summary>
	/// 持续时间(单位:H)
	/// </summary>
	public int Duration;

	public static TimeCycleConfig[] GetDatas(){
    
     
		return Datas;
	}

// TimeCycleConfig 共计 [1] 条数据

	public static TimeCycleConfig[] Datas = new TimeCycleConfig[]{
    
    
		new TimeCycleConfig{
    
     Id=1, Disc="破冰礼包(首购礼包)", DateRule=1, CyclePeriod=3, StartTime=0, Duration=48, },
	};
}

循环管理器:

using Newtonsoft.Json;
using SG.Utils;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class TimeCycleManager : MonoSingleton<TimeCycleManager>
{
    
    
    #region 内部循环数据类定义
    public enum TimeCycleEvent
    {
    
    
        //循环更新,1秒更新一次
        Update,
    }
    public enum TimeCycleStatus
    {
    
    
        NotOpen, //未开启
        Running,  //进行中
        Finished   //当前周期已结束
    }
    [Serializable]
    public class CycleData
    {
    
    
        public TimeCycleStatus mStatus;
        public TimeCycleConfig mConf;
        //剩余时间,单位秒
        public int mLeftTime = 0;

        //获取本周期当前时间减去开始时间差值,单位秒
        int GetLeftTime()
        {
    
    
            var now = DateTime.Now;
            int escapeDays = GetEscapeDays(now);
            int escapeHours = now.Hour + escapeDays * 24;
            if (escapeHours < mConf.StartTime) //没有开始
            {
    
    
                mStatus = TimeCycleStatus.NotOpen;
                return 0;
            }
            else if (escapeHours >= mConf.StartTime + mConf.Duration) //已经结束
            {
    
    
                mStatus = TimeCycleStatus.Finished;
                return 0;
            }
            else
            {
    
    
                mStatus = TimeCycleStatus.Running;
                return (mConf.StartTime + mConf.Duration - escapeHours - 1) * 60 * 60 + (60 - now.Minute - 1) * 60 + (60 - now.Second);
            }
        }

        int GetEscapeDays(DateTime date)
        {
    
    
            if (mConf.DateRule == 1)
            {
    
    
                return (int)(TimeManager.Instance.SortLoginDay - 1) % mConf.CyclePeriod;
            }
            else if (mConf.DateRule == 2)
            {
    
    
                return (int)(TimeManager.Instance.AllLoginDay - 1) % mConf.CyclePeriod;
            }
            else if (mConf.DateRule == 3) //以周开始的话,周一为第一天
            {
    
    
                if (date.DayOfWeek == DayOfWeek.Sunday)
                {
    
    
                    return 6;
                }
                else
                {
    
    
                    return (int)date.DayOfWeek - 1;
                }
            }
            else if (mConf.DateRule == 4)
            {
    
    
                return date.Month - 1;
            }
            return 10000000;
        }
        //TimeCycleManager调用,每秒更新一次
        public void OnUpdatePerSec()
        {
    
    
            this.mLeftTime = GetLeftTime();
            GameEventMgr.Instance.SendEvent(TimeCycleEvent.Update, this);
        }
    }
    #endregion

    [SerializeField]
    List<CycleData> mCycleDataList = new List<CycleData>();

    public new void Init()
    {
    
    
        base.Init();
        foreach (var item in TimeCycleConfig.Datas)
        {
    
    
            mCycleDataList.Add(new CycleData
            {
    
    
                mConf = item
            });
        }
        StartCoroutine(UpdatePerSec());

    }

    public CycleData GetCycleData(int cycleId)
    {
    
    
        foreach (var item in mCycleDataList)
        {
    
    
            if (item.mConf.Id == cycleId)
            {
    
    
                return item;
            }
        }
        return null;
    }
    IEnumerator UpdatePerSec()
    {
    
    
        var wait = new WaitForSeconds(1);
        while (true)
        {
    
    
            try
            {
    
    
                //延迟原因:避免TimeManager登录日期尚未更新(其他文章中)
                DelayTimeManager.Instance.delay_time_run(0.2f, delegate
                {
    
    
                    foreach (var cycleData in mCycleDataList)
                    {
    
    
                        cycleData.OnUpdatePerSec();
                    }
                });
            }
            catch (Exception e)
            {
    
    
                DebugUtils.LogError(e.Message + "/n" + e.StackTrace);
            }
            yield return wait;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lcl20093466/article/details/128248421
今日推荐