农场游戏中的时间管理实例
一、准备工作
在Unity中创建承载日期和时间的文本

二、设置游戏的时间戳
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//标识这个类可以被序列化
[System.Serializable]
public class GameTimestamp
{// 游戏时间戳的成员变量public int year;//季节的枚举类型public enum Season { Spring, Summer, Fall, Winter }//星期几的枚举类型public enum DayOfTheWeek { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }public Season season;public int day;public int hour;public int minute;// 构造函数1:根据给定的参数创建一个游戏时间戳实例public GameTimestamp(int year, Season season, int day, int hour, int minute){this.year = year;this.season = season;this.day = day;this.hour = hour;this.minute = minute;}// 构造函数2:复制给定的游戏时间戳实例public GameTimestamp(GameTimestamp timestamp){this.year = timestamp.year;this.season = timestamp.season;this.day = timestamp.day;this.hour = timestamp.hour;this.minute = timestamp.minute;}// 更新游戏时钟public void UpdateClock(){minute++;if (minute >= 60) { minute = 0; hour++; }if (hour >= 24) { hour = 0; day++; }if (day > 30){day = 1;if (season == Season.Winter) { season = Season.Spring; year++; }else { season++; }}}// 获得当天是星期几public DayOfTheWeek GetDayOfTheWeek(){int daysPassed = YearsToDays(year) + SeasonsToDays(season) + day;int dayIndex = daysPassed % 7;return (DayOfTheWeek)dayIndex;}// 将小时转换为分钟数public static int HoursToMinutes(int hour) { return hour * 60; }// 将天数转换为小时数public static int DaysToHours(int days) { return days * 24; }// 将季节转换为天数public static int SeasonsToDays(Season season){int seasonIndex = (int)season;return seasonIndex * 30;}// 将年份转化为天数public static int YearsToDays(int year) { return year * 4 * 30; }// 比较两个不同的时间戳的差异public static int CompareTimestamp(GameTimestamp timestamp1, GameTimestamp timestamp2){int timestamp1Hours = DaysToHours(YearsToDays(timestamp1.year)) + DaysToHours(SeasonsToDays(timestamp1.season) + DaysToHours(timestamp1.day) + timestamp1.hour);int timestamp2Hours = DaysToHours(YearsToDays(timestamp2.year)) + DaysToHours(SeasonsToDays(timestamp2.season) + DaysToHours(timestamp2.day) + timestamp2.hour);int difference = timestamp1Hours - timestamp2Hours;//返回 difference 的绝对值。//Mathf.Abs 是 Unity 引擎中的一个数学函数,用于计算一个数的绝对值。//在这个脚本中,它用于计算两个时间戳之间的差异,并返回一个非负值return Mathf.Abs(difference);}
}
三、设置时间流逝逻辑
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TimeManager : MonoBehaviour
{// 创建一个单例对象,其他脚本可以通过Instance访问public static TimeManager Instance { get; private set; }// 当脚本被实例化时调用的方法,用于初始化实例private void Awake(){// 如果Instance已经存在并且不等于当前实例,则销毁当前实例if (Instance != null && Instance != this) { Destroy(this); }else { Instance = this; }}//序列化字段[SerializeField]// 游戏的时间戳GameTimestamp timestamp;// 游戏的时间缩放比例(时间流逝速度)public float timeScale = 1.0f;// 游戏开始时调用的方法void Start(){// 初始化时间戳为游戏开始时的时间timestamp = new GameTimestamp(0, GameTimestamp.Season.Spring, 1, 6, 0);// 开始一个协程来更新游戏时间StartCoroutine(TimeUpdate());}// 游戏时间更新的协程IEnumerator TimeUpdate(){while (true){// 每隔1 / timeScale秒执行一次Tick方法Tick();yield return new WaitForSeconds(1 / timeScale);}}// 每次游戏时间更新时调用的方法public void Tick(){// 更新时间戳timestamp.UpdateClock();}
}
四、日夜循环
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TimeManager : MonoBehaviour
{public static TimeManager Instance { get; private set; }private void Awake(){if (Instance != null && Instance != this) { Destroy(this); }else { Instance = this; }}[SerializeField]GameTimestamp timestamp;public float timeScale = 1.0f;//将一个用于表示白天和黑夜循环的Transform赋值给sunTransform变量,并声明一个ITimeTracker接口类型的列表listeners,用于保存所有注册的时间追踪器。[Header("Day and Night cycle")]public Transform sunTransform;List<ITimeTracker> listeners = new List<ITimeTracker>();void Start(){timestamp = new GameTimestamp(0, GameTimestamp.Season.Spring, 1, 6, 0);StartCoroutine(TimeUpdate());}IEnumerator TimeUpdate(){while (true){Tick();yield return new WaitForSeconds(1 / timeScale);}}public void Tick(){//更新时间戳timestamp.UpdateClock();//通知所有注册的时间追踪器更新时间foreach (ITimeTracker listener in listeners){listener.ClockUpdate(timestamp);}//调用UpdateSunMovement方法更新太阳的位置UpdateSunMovement();}void UpdateSunMovement(){//当前时间int timeInMinutes = GameTimestamp.HoursToMinutes(timestamp.hour) + timestamp.minute;//计算太阳的角度float sunAngle = .25f * timeInMinutes - 90;//将太阳角度应用到sunTransform的欧拉角上,实现太阳的运动sunTransform.eulerAngles = new Vector3(sunAngle, 0, 0);}//获取新的时间戳public GameTimestamp GetGameTimestamp(){//返回当前的时间戳return new GameTimestamp(timestamp);}//将一个时间追踪器注册到列表中public void RegisterTracker(ITimeTracker listener){listeners.Add(listener);}//将一个时间追踪器从列表中移除public void UnregisterTracker(ITimeTracker listener){listeners.Remove(listener);}
}
五、测试方法
public class PlayerController : MonoBehaviourvoid Update()
{//测试光线逻辑if(Input.GetKey(KeyCode.RightBracket)){TimeManager.Instance.Tick();}
}
按住右方括号,加速时间流速
六、创建接口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public interface ITimeTracker
{void ClockUpdate(GameTimestamp timestamp);
}
七、显示游戏时间
1、编辑UIManager.cs,游戏时间
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//添加接口,管理时间
public class UIManager : MonoBehaviour, ITimeTracker
{public static UIManager Instance { get; private set; }private void Awake(){if (Instance != null && Instance != this) { Destroy(this); }else { Instance = this; }}[Header("Startas Bar")]//手持工具栏中的时间文本public Text timeText;public Text dateText;private void Start(){//注册时间跟踪器(将UIManager添加到时间跟踪器的列表中)TimeManager.Instance.RegisterTracker(this);}//处理UI时间回调(回调:在特定的时刻执行自己定义的代码,实现特定的功能)//更新游戏中的时钟public void ClockUpdate(GameTimestamp timestamp){//获取小时和分钟的值int hours = timestamp.hour;int minutes = timestamp.minute;string prefix = "AM ";//转换为下午的时间if (hours > 12){prefix = "PM ";hours -= 12;}timeText.text = prefix + hours + ":" + minutes.ToString("00");//获取日期\星期int day = timestamp.day;string season = timestamp.season.ToString();string dayOfTheWeek = timestamp.GetDayOfTheWeek().ToString();dateText.text = season + " " + day + " (" + dayOfTheWeek +")";}
}
2、赋值
八、把时间系统运用到耕地上
1、编辑TimeManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TimeManager : MonoBehaviour
{public static TimeManager Instance { get; private set; }private void Awake(){if (Instance != null && Instance != this) { Destroy(this); }else { Instance = this; }}[SerializeField]GameTimestamp timestamp;public float timeScale = 1.0f;[Header("Day and Night cycle")]public Transform sunTransform;List<ITimeTracker> listeners = new List<ITimeTracker>();void Start(){timestamp = new GameTimestamp(0, GameTimestamp.Season.Spring, 1, 6, 0);StartCoroutine(TimeUpdate());}IEnumerator TimeUpdate(){while (true){Tick();yield return new WaitForSeconds(1 / timeScale);}}public void Tick(){timestamp.UpdateClock();foreach (ITimeTracker listener in listeners){listener.ClockUpdate(timestamp);}UpdateSunMovement();}void UpdateSunMovement(){int timeInMinutes = GameTimestamp.HoursToMinutes(timestamp.hour) + timestamp.minute;float sunAngle = .25f * timeInMinutes - 90;sunTransform.eulerAngles = new Vector3(sunAngle, 0, 0);}//获取新的时间戳public GameTimestamp GetGameTimestamp(){return new GameTimestamp(timestamp);}public void RegisterTracker(ITimeTracker listener){listeners.Add(listener);}public void UnregisterTracker(ITimeTracker listener){listeners.Remove(listener);}
}
2、编辑Land.cs,设置灌溉后土壤变化
using System.Collections;
using System.Collections.Generic;
using UnityEngine;//添加接口
public class Land : MonoBehaviour, ITimeTracker
{public enum LandStatus { Soil, Farmland, Watered }public LandStatus landStatus;public Material soilMat, farmlandMat, wateredMat;new Renderer renderer;public GameObject select;//灌溉时间GameTimestamp timeWatered;void Start(){renderer = GetComponent<Renderer>();SwitchLandStatus(LandStatus.Soil);//select.SetActive(false);Select(false);//注册时间戳TimeManager.Instance.RegisterTracker(this);}public void SwitchLandStatus(LandStatus statusToSwitch){landStatus = statusToSwitch;Material materialToSwitch = soilMat;switch (statusToSwitch){case LandStatus.Soil: materialToSwitch = soilMat; break;case LandStatus.Farmland: materialToSwitch = farmlandMat; break;//灌溉后土壤状态case LandStatus.Watered:materialToSwitch = wateredMat;//灌溉后流逝的时间timeWatered = TimeManager.Instance.GetGameTimestamp();break;}renderer.material = materialToSwitch;}public void Select(bool toggle){select.SetActive(toggle);}public void Interact(){ItemData toolSlot = InventoryManager.Instance.equippedTool;EquipmentData equipmentTool = toolSlot as EquipmentData;if (equipmentTool != null){EquipmentData.ToolType toolType = equipmentTool.toolType;switch (toolType){case EquipmentData.ToolType.Hoe:SwitchLandStatus(LandStatus.Farmland); break;case EquipmentData.ToolType.WateringCan:SwitchLandStatus(LandStatus.Watered); break;}}}//设置灌溉后土壤的变化public void ClockUpdate(GameTimestamp timestamp){if (landStatus == LandStatus.Watered){int hoursElapsed = GameTimestamp.CompareTimestamp(timeWatered, timestamp);Debug.Log(hoursElapsed + "上次灌溉时间");if (hoursElapsed > 24){SwitchLandStatus(LandStatus.Farmland);}}}
}相关文章:
农场游戏中的时间管理实例
一、准备工作 在Unity中创建承载日期和时间的文本 二、设置游戏的时间戳 using System.Collections; using System.Collections.Generic; using UnityEngine; //标识这个类可以被序列化 [System.Serializable] public class GameTimestamp {// 游戏时间戳的成员变量public in…...
css 数字平铺布局
效果图 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>活动中心</title><meta name"viewport" content"maximum-scale1.0,minimum-scale1.0,user-scalable0,widthdevice-width,initial-scale1.0…...
【开源】嵌入式Linux(IMX6U)应用层综合项目(2)--智能家居APP
目录 1.简介 1.1功能介绍 1.2技术栈介绍 1.3演示视频 1.4硬件介绍 2.软件设计 2.1智能家居UI设计 2.2.main函数 3.结尾(附网盘链接) 1.简介 此文章并不是教程,只能当作笔者的学习分享,只会做一些简单的介绍,其…...
CUDA常见编译器配置问题一览
CUDA常见编译器配置问题一览 关注TechLead,复旦博士,分享云服务领域全维度开发技术。拥有10年互联网服务架构、AI产品研发经验、团队管理经验,复旦机器人智能实验室成员,国家级大学生赛事评审专家,发表多篇SCI核心期刊…...
【Android】系统级应用升级后的安装位置
系统级应用的安装位置一般在codePath/system 下面, 如果手动的去进行adb install覆盖安装,通过dumpsys package可以发现是安装在/data/app/里, 如果是通过标准的系统升级方式呢? 这里我们来通过升级查看一下, 升级…...
uniapp 使用renderjs通信
一、 server层向renderjs传值,并初始化renderjs prop:可以随便定义 renderTaskDetail:是传往renderjs的数据 change:prop:prop和必须上面prop字段一样 renderScript.initAmap:【 renderScript】需要renderjs 中scr…...
PostgreSQL 15
一、安装前的准备 1、版本信息 操作系统CentOS 7.9.2009PostgreSQL 版本PostgreSQL 15-15.7 2、下载安装包 RPM Chart - PostgreSQL YUM Repositoryhttps://yum.postgresql.org/rpmchart/进入官网,找到相应版本 点击框选内容 依次进入下载页面,下载相…...
给本地设备搭建一个云端语音助手
概述 本语音助手实现了从关键词唤醒 (KWS) 到语音识别 (ASR) 再到自然语言理解 (NLU) 的完整流程。该系统可以通过监听用户的音频输入,检测指定的关键词,并将用户的语音转换为文本,最后与预设的命令进行匹配,执行相应的操作(具体实现请参考main.py),为你的设备配置远程…...
yolov5车辆类型识别TXT数据集
YOLOV5训练车辆类型识别TXT数据集, 一共1400张图片,共分7个类別, 分别为Bus,Car,SportsCar,MicroBus,Truck,SUV,Jeep是TXT格式的数据集,用LabelImg工具进行标…...
day22(mysql数据库主从搭建)
上午: 1、为mysql添加开机启动chkconfig 2、编辑配置文件my.cnf 3、修改环境变量 4、mysql角色授权 角色不生效 在配置文件中不添加activate_all_roles_on_loginon glibc安装,my.cnf在项目目录之下 rpm安装,my.cnf文件在/etc/my.cnf 5、自…...
返璞归真:通过简化用例来简化用户界面01
Larry Constantine 著harvey 译 我们常被问及精简那些最简化、抽象和通用窗体用例的重要性。到底有多重要呢?在以用户为 中心的设计中,简化那些重要窗体的用例是获得成功的关键。它能够为开发者设计优秀的用户界面 助一臂之力。通过消除不必要的或技术驱…...
书生大模型学习笔记2 - Python
Python实现wordcount 请实现一个wordcount函数,统计英文字符串中每个单词出现的次数。返回一个字典,key为单词,value为对应单词出现的次数。 解题思路:首先把字母转小写>然后把单词取出来去除标点>循环单词列表>key已存…...
JavaScript三级联动jQuery写法
HTML结构 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>三级联动</title><!-- <style…...
无人机挂载抓捕网
一、技术原理与机制 无人机挂载抓捕网装置的技术原理是通过无人机平台的飞行能力和灵活性,结合特制的抓捕网装置,实现对目标的快速、准确抓捕。抓捕网装置在接收到指令后,通过特定机制快速展开并包围目标,从而实现抓捕任务。 二…...
174.地下城游戏——LeetCode
题目 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻…...
登录相关功能的优化【JWT令牌+拦截器+跨域】
登录相关功能的优化 登录后显示当前登录用户el-dropdown: Element - The worlds most popular Vue UI framework <el-dropdown style"float: right; height: 60px; line-height: 60px"><span class"el-dropdown-link" style"color: white;…...
向日葵没有显示器会卡住
前言 有一台机器【ubuntu20】,用于远程开发,使用向日葵时候,如果不接显示器是会卡住的。。。 显示屏是有限的,所以现在解决一下这个问题。 卡在登录界面 双击启动 由于Ubuntu默认显示管理器是gdm,而向日葵使用的是l…...
【机器学习西瓜书学习笔记——聚类】
机器学习西瓜书学习笔记【第九章】 第九章 聚类9.1 聚类任务9.2 性能度量两类指标 9.3距离计算基本性质属性有序属性无序属性 混合距离加权距离 9.4 原型聚类K-MEANS聚类算法步骤优势劣势 学习向量量化高斯混合聚类步骤难点例子EM思想的体现小结 9.5 密度聚类9.6 层次聚类 第九…...
MATLAB(8)深度变化模型
一、前言 在MATLAB中模拟深度变化模型通常依赖于具体的应用场景,比如海洋深度、地下水深度、地形高度变化等。由于“深度变化”可以涉及多种物理过程和数学模型,我将提供一个简化的示例,该示例模拟了一个基于时间变化的深度变化模型ÿ…...
mp3格式转换器哪个好用?汇总七款音频格式转换方法(无损转换)
音乐已经成为我们生活中不可或缺的一部分。但是在播放的时候,可能会遇到音频格式不兼容的情况。特别是在一些下载站或音乐平台获取的音频,有些特殊格式在播放器上无法正常播放,一般这种情况我们需要借助mp3转换器解决。 mp3是一种常见的数字音…...
SpringCloud OAuth2与JWT:构建无状态微服务安全体系的实践指南
1. 为什么微服务需要无状态安全方案 记得去年我参与重构一个电商系统时,遇到一个典型问题:每次大促期间,Redis集群就会因为Session查询压力过大而崩溃。这个痛点让我深刻理解了传统Session方案在微服务架构中的局限性。 传统Session方案就像…...
告别代码恐惧:用自然语言让AI成为你的全平台操作助手
告别代码恐惧:用自然语言让AI成为你的全平台操作助手 【免费下载链接】midscene AI-powered, vision-driven UI automation for every platform. 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene 还在为复杂的自动化脚本而头疼吗?想…...
3大难题如何破解:猫抓浏览器资源嗅探扩展终极指南
3大难题如何破解:猫抓浏览器资源嗅探扩展终极指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓(cat-catchÿ…...
Chandra OCR完整教程:从单图测试到企业级应用,全流程实战解析
Chandra OCR完整教程:从单图测试到企业级应用,全流程实战解析 1. Chandra OCR核心能力解析 Chandra OCR是Datalab.to在2025年开源的一款革命性文档识别工具,与传统OCR相比具有三大突破性优势: 布局感知:不仅能识别文…...
Android OAID 集成实战:基于 MSA SDK 1.0.25 的避坑指南与多厂商适配
1. 为什么需要OAID?从IMEI到匿名标识的演进之路 几年前我做广告归因项目时,突然发现获取不到设备的IMEI了。当时第一反应是代码出了问题,反复检查权限声明和API调用,直到看到系统日志里醒目的"READ_PHONE_STATE permission …...
DeOldify性能调优实战:针对显存与推理速度的优化策略
DeOldify性能调优实战:针对显存与推理速度的优化策略 你是不是也遇到过这种情况?好不容易部署好了DeOldify,准备给家里的老照片上色,结果一运行,程序就报错,提示显存不足。或者,虽然能跑起来&a…...
深度解析 Chromium WebUI 的生命周期与 IsJavascriptAllowed 崩溃之谜
在 Chromium (或基于其二次开发的浏览器等内核) 开发中,WebUI 是我们最常打交道的模块之一。诸如 chrome://settings、chrome://history 这些内置页面,都是通过 WebUI 机制实现前端 (HTML/JS) 与底层 C 的双向通信。然而,在处理后台异步任务向…...
【实盘】20260409 :+3.42% 对资管而言,曲线就是生命线!
一、20260409 - 平仓净值曲线 01 CTA投资组合团队自营CTA(Commodity Trading Advisor)多品种全天候自动化策略,是一类基于截面双动量因子的量化模型、覆盖全交易时段、跨多品种期货合约的自动化交易策略,核心目标是通过捕捉不同品…...
Gophish实战指南:从零构建邮件钓鱼实验环境
1. Gophish简介与核心功能 Gophish是一款专为企业和安全团队设计的开源钓鱼模拟工具,它让安全测试人员能够快速搭建逼真的钓鱼攻击环境。我第一次接触这个工具是在2018年的一次内部安全演练中,当时我们需要测试公司员工的网络安全意识,但市面…...
HALCON机器视觉多线程编程实战:从线程安全到性能优化
1. HALCON多线程编程基础入门 第一次接触HALCON多线程编程时,我踩过不少坑。记得有次在产线检测项目中,为了提高图像处理速度,我直接开了8个线程同时处理图像,结果程序反而比单线程时更慢了。后来才发现,多线程编程不是…...
