1、目标
创建一个时间管理类,它将管理一年的四季、日、周、时、分、秒,也与时间的触发事件有关。
本小节只需要将当前时间打印到控制台。
2、思路
通过累加TimeDelta时间得到秒数,通过秒继而得到分、时、天、季节、年的信息。
通过Event事件更新时间。
3、优化Enums.cs脚本
新增如下内容:
public enum Season
{Spring,Summer,Autumn,Winter,none,count
}
4、优化Settings.cs脚本
增加如下内容:
// Time System
public const float secondsPerGameSecond = 0.012f;
一秒钟对应的TimeDelta累加时间。
5、优化EventHandler.cs脚本
增如如下代码:
// Advance game minute
public static event Action<int, Season, int, string, int, int, int> AdvanceGameMinuteEvent;public static void CallAdvanceGameMinuteEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond)
{if(AdvanceGameMinuteEvent != null){AdvanceGameMinuteEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}
}// Advance game hour
public static event Action<int, Season, int, string, int, int, int> AdvanceGameHourEvent;public static void CallAdvanceGameHourEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond)
{if (AdvanceGameHourEvent != null){AdvanceGameHourEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}
}// Advance game day
public static event Action<int, Season, int, string, int, int, int> AdvanceGameDayEvent;public static void CallAdvanceGameDayEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond)
{if (AdvanceGameDayEvent != null){AdvanceGameDayEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}
}// Advance game season
public static event Action<int, Season, int, string, int, int, int> AdvanceGameSeasonEvent;public static void CallAdvanceGameSeasonEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond)
{if (AdvanceGameSeasonEvent != null){AdvanceGameSeasonEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}
}// Advance game year
public static event Action<int, Season, int, string, int, int, int> AdvanceGameYearEvent;public static void CallAdvanceGameYearEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond)
{if (AdvanceGameYearEvent != null){AdvanceGameYearEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}
}
完整代码如下:
using System;
using System.Collections.Generic;
using UnityEngine;public delegate void MovementDelegate(float inputX, float inputY, bool isWalking, bool isRunning, bool isIdle, bool isCarrying, ToolEffect toolEffect, bool isUsingToolRight, bool isUsingToolLeft, bool isUsingToolUp, bool isUsingToolDown, bool isLiftingToolRight, bool isLiftingToolLeft, bool isLiftingToolUp, bool isLiftingToolDown, bool isPickingRight, bool isPickingLeft, bool isPickingUp, bool isPickingDown, bool isSwingToolRight, bool isSwingToolLeft, bool isSwingToolUp, bool isSwingToolDown, bool idleUp, bool idleDown, bool idleLeft, bool idleRight);public static class EventHandler
{// Inventory Updated Eventpublic static event Action<InventoryLocation, List<InventoryItem>> InventoryUpdatedEvent;public static void CallInventoryUpdatedEvent(InventoryLocation inventoryLocation, List<InventoryItem> inventoryList){if(InventoryUpdatedEvent != null) // 有订阅者{InventoryUpdatedEvent(inventoryLocation, inventoryList);}}// Movement Eventpublic static event MovementDelegate MovementEvent;// Movement Event Call For Publisherspublic static void CallMovementEvent(float inputX, float inputY, bool isWalking, bool isRunning, bool isIdle, bool isCarrying,ToolEffect toolEffect,bool isUsingToolRight, bool isUsingToolLeft, bool isUsingToolUp, bool isUsingToolDown,bool isLiftingToolRight, bool isLiftingToolLeft, bool isLiftingToolUp, bool isLiftingToolDown,bool isPickingRight, bool isPickingLeft, bool isPickingUp, bool isPickingDown,bool isSwingToolRight, bool isSwingToolLeft, bool isSwingToolUp, bool isSwingToolDown,bool idleUp, bool idleDown, bool idleLeft, bool idleRight){if (MovementEvent != null){MovementEvent(inputX, inputY, isWalking, isRunning, isIdle, isCarrying,toolEffect,isUsingToolRight, isUsingToolLeft, isUsingToolUp, isUsingToolDown,isLiftingToolRight, isLiftingToolLeft, isLiftingToolUp, isLiftingToolDown,isPickingRight, isPickingLeft, isPickingUp, isPickingDown,isSwingToolRight, isSwingToolLeft, isSwingToolUp, isSwingToolDown,idleUp, idleDown, idleLeft, idleRight);}}// Time Events// Advance game minutepublic static event Action<int, Season, int, string, int, int, int> AdvanceGameMinuteEvent;public static void CallAdvanceGameMinuteEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond){if(AdvanceGameMinuteEvent != null){AdvanceGameMinuteEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}}// Advance game hourpublic static event Action<int, Season, int, string, int, int, int> AdvanceGameHourEvent;public static void CallAdvanceGameHourEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond){if (AdvanceGameHourEvent != null){AdvanceGameHourEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}}// Advance game daypublic static event Action<int, Season, int, string, int, int, int> AdvanceGameDayEvent;public static void CallAdvanceGameDayEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond){if (AdvanceGameDayEvent != null){AdvanceGameDayEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}}// Advance game seasonpublic static event Action<int, Season, int, string, int, int, int> AdvanceGameSeasonEvent;public static void CallAdvanceGameSeasonEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond){if (AdvanceGameSeasonEvent != null){AdvanceGameSeasonEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}}// Advance game yearpublic static event Action<int, Season, int, string, int, int, int> AdvanceGameYearEvent;public static void CallAdvanceGameYearEvent(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond){if (AdvanceGameYearEvent != null){AdvanceGameYearEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}}
}
6、创建TimeManager.cs脚本
在Assets -> Scripts下新建TimeSystem目录,在其下新建TimeManager.cs脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TimeManager : SingletonMonobehaviour<TimeManager>
{private int gameYear = 1;private Season gameSeason = Season.Spring;private int gameDay = 1;private int gameHour = 6;private int gameMinute = 30;private int gameSecond = 0;private string gameDayOfWeek = "Mon";private bool gameClockPaused = false;private float gameTick = 0f;private void Start(){EventHandler.CallAdvanceGameMinuteEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}private void Update(){if (!gameClockPaused){GameTick();}}private void GameTick(){gameTick += Time.deltaTime;if(gameTick >= Settings.secondsPerGameSecond){gameTick -= Settings.secondsPerGameSecond; // 减完重新开始UpdateGameSecond();}}private void UpdateGameSecond(){gameSecond++;if(gameSecond > 59){gameSecond = 0;gameMinute++;if(gameMinute > 59){gameMinute = 0;gameHour++;if(gameHour > 23){gameHour = 0;gameDay++;if(gameDay > 30){gameDay = 1;int gs = (int)gameSeason;gs++;gameSeason = (Season)gs;if(gs > 3){gs = 0;gameSeason = (Season)gs;gameYear++;EventHandler.CallAdvanceGameYearEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}EventHandler.CallAdvanceGameSeasonEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}gameDayOfWeek = GetDayOfWeek();EventHandler.CallAdvanceGameDayEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}EventHandler.CallAdvanceGameHourEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);}EventHandler.CallAdvanceGameMinuteEvent(gameYear, gameSeason, gameDay, gameDayOfWeek, gameHour, gameMinute, gameSecond);Debug.Log("Game Year: " + gameYear + " Game Season: " + gameSeason + " Game Day: " + gameDay + " Game Hour: " + gameHour + " Game Minute: " + gameMinute);}}private string GetDayOfWeek(){int totalDays = (((int)gameSeason) * 30) + gameDay;int dayOfWeek = totalDays % 7;switch (dayOfWeek){case 1:return "Mon";case 2:return "Tue";case 3:return "Wed";case 4:return "Thu";case 5:return "Fri";case 6:return "Sat";case 7:return "Sun";default:return "";}}
}
在Hierarchy -> PersistentScene下创建空对象命名为TimeManager,并且挂载TimeManager脚本。
运行程序,控制台日志如下: