农场游戏中的时间管理实例
一、准备工作
在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是一种常见的数字音…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
