农场游戏中的时间管理实例
一、准备工作
在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是一种常见的数字音…...

移行前的复盘:CodeCommit 的重要地位分析
前言 截至7月28日,关于AWS CodeCommit的现状如下: 现有账号的现有存储库可以继续使用CodeCommit,不受限制。之前未使用过CodeCommit的账号(或没有现有存储库的账号)无法创建新的存储库。 这并不意味着CodeCommit的服…...

Java中等题-括号生成(力扣)
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 示例 1: 输入:n 3 输出:["((()))","(()())","(())()","()(())","()()(…...

Flink 实时数仓(八)【DWS 层搭建(二)流量域、用户域、交易域搭建】
前言 今天的任务是完成流量域最后一个需求、用户域的两个需求以及交易域的部分需求; 1、流量域页面浏览各窗口汇总表 任务:从 Kafka 页面日志主题读取数据,统计当日的首页和商品详情页独立访客数。 注意:一般我们谈到访客&…...

gitlab-runner /var/run/docker.sock connect permission denied
usermod -aG docker gitlab-runner sudo service docker restart参考:https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3492...

网络安全 - 应急响应检查表
前言 本项目旨在为应急响应提供全方位辅助,以便快速解决问题。结合自身经验和网络资料,形成检查清单,期待大家提供更多技巧,共同完善本项目。愿大家在应急之路一帆风顺。 图片皆来源于网络,如有侵权请联系删除。 一…...

AD常用PCB设计规则介绍 (详细版)
AD09常用PCB设计规则介绍 电气设计规则用来设置在电路板布线过程中所遵循的电气方面的规则,包括安全间距、短路、未布线网络和未连接引脚这四个方面的规则: (1)、安全间距规则(clearance) 该规则用于设定在PCB设计中࿰…...

mysql主从服务配置
主从MySQL服务器 [rootlocalhost ~]# yum -y install ntpdate [rootlocalhost ~]# ntpdate cn.ntp.org.cn [rootlocalhost ~]# yum -y install rsync [rootlocalhost ~]# vim mysql.sh #!/bin/bash yum list installed |grep libaio if [ $? ne 0 ]; then yum -y install…...

Redis基础总结、持久化、主从复制、哨兵模式、内存淘汰策略、缓存
文章目录 Redis 基础Redis 是什么,有哪些特点为什么要使用 Redis 而不仅仅依赖 MySQLRedis 是单线程吗Redis 单线程为什么还这么快 Redis 数据类型和数据结构五种基本数据结构及应用场景其他数据类型Redis 底层数据结构 Redis 持久化数据不丢失的实现AOF 日志RDB 快…...

Java与Python优劣势对比:具体例子与深入分析
在软件开发的世界里,Java和Python是两座不可忽视的高峰。它们各自拥有独特的优势和应用场景,为开发者提供了多样化的选择。本文将通过具体例子,深入分析Java和Python在不同方面的表现,以期为读者提供更为详尽的参考。 1. 语法简洁…...

C++内存泄漏介绍
C内存泄漏(Memory Leak)是指程序在运行过程中,动态分配的内存没有被适当地释放或回收,导致这部分内存始终被占用,无法再被程序或其他程序使用。这种情况通常发生在使用了new或malloc等函数动态分配内存后,忘…...