当前位置: 首页 > article >正文

Unity3D仿星露谷物语开发24之创建时间管理器

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 Event
    public static event Action<InventoryLocation, List<InventoryItem>> InventoryUpdatedEvent;

    public static void CallInventoryUpdatedEvent(InventoryLocation inventoryLocation, List<InventoryItem> inventoryList)
    {
        if(InventoryUpdatedEvent != null) // 有订阅者
        {
            InventoryUpdatedEvent(inventoryLocation, inventoryList);
        }
    }



    // Movement Event
    public static event MovementDelegate MovementEvent;

    // Movement Event Call For Publishers
    public 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 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);
        }
    }
}

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脚本。

运行程序,控制台日志如下:


http://www.kler.cn/a/511628.html

相关文章:

  • 【Kafka】Linux+KRaft集群部署指南
  • 在 Ubuntu 上安装 Jetzig 框架指南
  • 【Java数据结构】优先级队列(堆)
  • KubeSphere 与 Pig 微服务平台的整合与优化:全流程容器化部署实践
  • ChatGPT 写作系列
  • 汇编与逆向(一)-汇编工具简介
  • 【24】Word:小郑-准考证❗
  • Windows 通过 openssh 连接 Ubuntu 24.04 LTS
  • leetcode300.最长递增子序列
  • css‘s hover VS mobile
  • UnderTow服务器
  • 第10章:Python TDD优化货币类方法与引入工厂方法
  • 【学习笔记15】如何在非root服务器中,安装属于自己的redis
  • rocketmq dashboard 安装
  • w-form-select.vue(自定义下拉框组件)
  • 1.写在前面
  • 【无标题】Cloudlog 电台日志系统 request_form SQL注入漏洞复现
  • Linux自学指南(学习路线大纲)
  • 【机器学习:三十三(二)、支持向量机(SVM)的核函数:概念、类型与应用】
  • PyTorch使用教程(8)-一文了解torchvision