Unity 离线建造系统

简介:

Unity 离线建造系统

很多游戏,特别是养成类手游,都会有自己独特的建造系统,一个建造装置的状态循环或者说生命周期一般是这样的:

1.准备建造,设置各项资源的投入等

2.等待一段倒计时,正在建造中

3.建造结束,选择是否收取资源

大体上,可以将建造盒子分为以下三种状态,每一个状态的逻辑和显示的页面不同:

1 public enum BuildBoxState
2 {
3 Start,
4 Doing,
5 Complete
6 }

1 private void ShiftState(BuildBoxState state)
2 {
3 switch (state)
4 {
5 case BuildBoxState.Start:
6 Start.SetActive(true);
7 Doing.SetActive(false);
8 Complete.SetActive(false);
9
10 ResetResCount();
11 break;
12 case BuildBoxState.Doing:
13 Start.SetActive(false);
14 Doing.SetActive(true);
15 Complete.SetActive(false);
16
17 StartCoroutine(ShowBuildTime());
18 break;
19 case BuildBoxState.Complete:
20 Start.SetActive(false);
21 Doing.SetActive(false);
22 Complete.SetActive(true);
23
24 break;
25 }
26 CurState = state;
27 }

这里值得思考的并非是状态的切换或者基础的按钮侦听,视图资源更新等。

如何在离线一段时间后重新获取目前对应建造盒子所处的状态才是重点;并且如果处于建造中状态的话,还应该能正确的显示剩余时间的倒计时。

一个非常常见的想法是,在建造开始时记录一份开始建造的时间数据给服务器或存在本地离线数据中,当下一次再登录时读取当前系统的时间,并通过总共需要的建造时长来计算剩余时间。

但假如总共需要的建造时长与当时投入的资源类型和量都有关系,这时就需要至少额外记载一类数据来进行计算。那么,有没有方法仅通过一个数据得到剩余时长呢?

答案是,不记录开始建造的时刻,改为记录拟定建造完成的时刻。

如此一来,每次离线登录后,只需要干两件事既可以判断出所有状态视图:

1.是否存在该建造盒子ID对应的拟定建造完成时刻的数据,如果不存在,一定是处于准备状态,即Start状态。

2.如果存在,对比当前系统时刻与拟定建造完成时刻的数据大小,大于等于则处于完成状态,小于则依然在建造中,并按秒显示差值更新。

记录的时刻如下:

1 public string BuildCompleteTime
2 {
3 get
4 {
5 if (PlayerPrefs.HasKey(ID.ToString()))
6 return PlayerPrefs.GetString(ID.ToString());
7 return S_Null;
8 }
9 set
10 {
11 PlayerPrefs.SetString(ID.ToString(), value);
12 PlayerPrefs.Save();
13 }
14 }

每次开始时,只需要判断这个数据是否存在:

1 protected override void InitState()
2 {
3 View = HudView as BuildBoxView;
4 if (BuildCompleteTime == S_Null)
5 {
6 ShiftState(BuildBoxState.Start);
7 }
8 else
9 {
10 ShiftState(BuildBoxState.Doing);
11 }
12 }

通过建造中的时刻关系自动判断是否完成:

1 IEnumerator ShowBuildTime()
2 {
3 var ct = GetCompleteTime();
4 if (CheckBuildCompleted(ct))
5 {
6 ShiftState(BuildBoxState.Complete);
7 yield break;
8 }
9 else
10 {
11 for (; ; )
12 {
13 View.SetTime(CalNeedTime(ct));
14 yield return new WaitForSeconds(1);
15 }
16 }
17 }

当建造完成点击收取资源时,切换为准备状态的同时,自动清空拟定建造完成时刻的数据记录:

1 private void OnClickGet()
2 {
3 Canvas.SendEvent(new GetItemEvent());
4 ClearCompleteTime();
5 ShiftState(BuildBoxState.Start);
6 }
这里有一个问题是,为什么不在建造完成时就清理数据呢,因为有一种情况是,建造完成后,玩家还没来得及点击收取,就直接进入了离线状态,如果此时再次登录时数据已经清空,那他将做了一场无用功。

说不定直接垃圾游戏毁我青春败我前程了,为了避免这种情况发生,我们只有确保玩家真正收取到资源的那一刻才能清理数据。

到此,整个建造的基础逻辑已经梳理完毕。如果要实现快速建造的话,也只不过是将拟定的完成时间直接设置为此刻即可。如果之前记录的是开始建造的时刻,此时又会进行更多额外计算。

接下来,关于时间的坑这里也略提一二吧,一开始我以为记录时刻只需要记录时分秒即可,因为最多的建造时长也不超过10小时一般,游戏要保证玩家每天登陆,不可能动用海量的时间去建造一个资源。

如若如此,策划很可能会马上被抓出来祭天,并被玩家评论区冰冷的口水淹没。

但后来写着写着就发现了一个问题,那就是好多天没登录的玩家怎么办,只记录时分秒根本没办法判断时间的早晚,后来想一会还是把日期也记录下来吧。

1 public struct TimeData
2 {
3 public int DayOfYear;
4 public int Hour;
5 public int Minute;
6 public int Second;
7 }

要是你问,那一年以上没登录怎么办,那只能说,你建造的资源已经被时光的齿轮碾碎了(允悲...)。后来突然想起来如果是某一年的最后一天呢...emm,还是老实写全吧:

1 public struct TimeData
2 {
3 public int Year;
4 public int DayOfYear;
5 public int Hour;
6 public int Minute;
7 public int Second;
8
9 public TimeData(int year,int dayOfYear,int hour,int minute,int second)
10 {
11 Year = year;
12 DayOfYear = dayOfYear;
13 Hour = hour;
14 Minute = minute;
15 Second = second;
16 }
17 }

完整时间数据管理脚本:

 View Code
完整建造脚本:

 View Code
 View Code
这里用到的UI基础类可详见之前写过的随笔:

https://www.cnblogs.com/koshio0219/p/12808063.html

单例模式:

https://www.cnblogs.com/koshio0219/p/11203631.html

补充:

通用确认弹窗:

 View Code

效果:

原文地址https://www.cnblogs.com/koshio0219/p/12988884.html

相关文章
|
4月前
|
编解码 前端开发 人机交互
【Unity 3D】UI系统中UGUI各个组件的详细讲解(附源码 超详细)
【Unity 3D】UI系统中UGUI各个组件的详细讲解(附源码 超详细)
72 0
|
4月前
|
人工智能 算法 图形学
Unity 动画系统基本概念
Unity 动画系统基本概念
|
10月前
|
图形学
unity-初级动画系统
unity-初级动画系统
70 0
|
Web App开发 开发工具 图形学
|
图形学 数据安全/隐私保护
还在用Unity开发游戏?那你就out了,试试用Unity做一个答题系统吧
大家都支持Unity是用来做游戏开发,比如说做2D游戏、3D游戏,或者工业虚拟仿真软件的开发。 其他Unity可以做的有很多,比如答题系统。 本篇就介绍答题系统的开发 这个答题系统,可以从文本文档中提取题目和分数,然后绑定到UI上,在答题的过程中,自动判断分数,自动判断正确率。 目的是实现一个可快速导入到项目中使用的小模块。
|
数据可视化 图形学
Unity Mecanim 动画系统简介
Unity Mecanim 动画系统简介
92 0
Unity Mecanim 动画系统简介
|
图形学
|
图形学
Unity 之 模拟王者荣耀七日签到系统
做一个模拟王者荣耀的签到系统,七日签到不可补签,下周自动重置。
363 0
Unity 之 模拟王者荣耀七日签到系统
|
API vr&ar 开发工具
Unity报错 之 版本升级到2020对输入系统封装不好用了
Unity 版本升级到2020,Input Manager 输入系统升级带来的问题处理。
443 0
Unity报错 之 版本升级到2020对输入系统封装不好用了
|
图形学
Unity导航 (寻路系统Nav Mesh Agent)
第一种 简单寻路 地面接触到的。到达目标点不用跳跃能够一直走路到达。 场景视图中简单搭设几个物体。 胶囊体为寻路者,黄球为目标点 红地板,绿色障碍物。 现将地板以及障碍物选中 在检视面板设置静态为Navigation Static 如图2 然后菜单栏选择窗口 Window –Navigation 然后选择All—Bake烘焙如图 有三个页面参数可以调节烘焙效果,参数具体参照圣典解释。
1859 0