[Unity] Unity-C#提高篇主循环(转载)

查看:1276 |回复:15 | 2015-11-11 09:42:40

您需要 登录 才可以下载或查看,没有账号?注册

x
从写一段程序,到写一个app,写一个游戏,到底其中有什么不同呢?一段程序的执行时间很短,一个应用的执行时间很长,仅此而已。

游戏中存在一个帧的概念。

111528l8q8et9t8hfuz7th.jpg.thumb.jpg

这个概念大家都知道,类比的话,它就是电影胶卷的格。一格出现一段时间,然后换下一格。

电影一秒24格,游戏用的是一秒30帧,60帧。

电影胶片是在镜头前一格一格的放映,游戏逻辑是在update中一帧一帧的执行。

那么Update函数的驱动是如何完成的呢?

这个东西就是主循环

先来看看一个基本的控制台程序

111616dut3ecg11fy7u3cc.png.thumb.jpg

唔,helloworld,这个程序我们已经很熟悉了。一闪而过的那个版本。因为他执行然后马上就结束了。

那么这个版本呢?



你会说,我去,你写了一个死循环。

是的,主循环就是一个死循环。有了这个死循环,一段程序就能逐渐成为一个应用,一个游戏。



让我们把update拆出来,是不是看起来有点熟悉了。



再来个OnStart,是不是更加熟悉了



原来unity的MonoBehaviour就是这样啊。



任何的程序中都存在着主循环,在常用的界面框架中,通常隐藏主循环,留下事件型的接口。

主循环很简单吧,仅仅是看起来这样。

游戏程序通常事件型的框架不多,大部分逻辑需要从主循环层次开始组建,也就是你需要对主循环的理解非常深,能够从主循环上创建很多种模式的逻辑。

我们开始来介绍几个常见的

主循环和定时器

试想如下需求,需要每三秒钟打印一条log,怎么做这个三秒钟的计时?

电影是24格,每秒钟24帧,稳定的,雷打不动。通过数帧就知道个大概。

可是大家都知道游戏的帧率是跳跃的,每一帧的时间不固定。

Unity提供了一个参数,告诉你上一帧开始,到这一帧开始经过的时间,单位为秒 Time.Deltatime;



因为每一帧开始到上一帧开始的间隔给你了。只要把他们累加起来,就是一个计时器。你可以用秒表确认一下这个程序,他的表现和你的秒表一样精准,分毫不差。

这就是一个计时器了,一个用不稳定的帧速率的主循环驱动的计时器。只是他光计时了,啥也没干,我们来让他做点什么。



这个计时器是最基本的一个逻辑,固定帧率在游戏中只是一个理想化状态,大部分情况下无法实现固定帧率。

几乎所有的游戏逻辑都涉及到计时问题,都会涉及到如何在浮动帧率时进行逻辑控制。

时间是连续累加的,请时刻记住这一点。

主循环与缓动

用定时器去驱动数值的变化,在一些情况下,被称为缓动,dotween,itween,名字里有个tween的这类库或者插件,都是做缓动的。

他们包装了各式各样的缓动的模式代码,帮你节约一点时间。

我们来让一个box 3秒钟从A点移动到B点,所有缓动的系统中都采用这样一个考虑方式,零为开始,一为结束。那么我们让我们的timer 几秒完成一个从零到一的过程,这就是一个缓动的周期。

就用我们之前的代码去考虑,我们的timer 加到3秒,然后变小,再到三,再变小,ok。直接给timer+=的时候乘一个系数可以改变timer变化的速度,可以调节为三秒钟完成从零到一,但是我们入门篇讲过,好代码从命名开始,既然他叫做timer,他就不应该从零到一,从零到一的标识的是缓动的进度。

取名为lerp



如上代码就完成了一个缓动逻辑,把这个脚本给一个cube,然后begin end 填入不一样的值,跑起来看看。

无论你用了什么高大上的缓动库,知其然总是有好处的,而这,就是缓动框架背后的事情。

主循环和状态机

入门篇我们就讲了一个时空观的问题,这个用程序的概念就是状态,图灵机、冯诺依曼机,是计算机的基础,这个基础说的就是状态机。

即使从更大的尺度来看,高级语言来看。在顺序执行的程序体系中,状态机依然是编程的基础。

我们前面告诉过大家单步调试,每一个断点,就是一个状态。

程序是由一个一个的状态构成的。

再从更大的尺度看,功能模块和程序结构的角度,状态机依然是功能的基础,我现在处于主菜单还是战斗菜单?我现在是在充值还是还消费?

同级别的功能某一时刻必然处于某一功能中,是我们的设计基础。

游戏框架从哪里开始,必然从状态的分割开始。有些框架提供了一个比状态机更高级一点的模式,导航器,其实也属于状态机,但是导航器记录着之前的状态,可以NavBack。

导航器模式是什么?随便点开一个手机app,点一个功能,再点一个功能,然后按back,back,这就是导航器。

现在由于手游流行起来,游戏界面效法了很多app的设计,所以现在导航器设计是一个非常主流的设计。

由于我们只是一个抛砖引玉的提高过程,我们这里不会去写一个导航器框架出来,我们只是去解释状态机背后的行为。

这个状态代码这么写,有点长,我们分两段来看,一段是update函数



一段是ongui函数



仔细看过这段代码,你也许会说,你骗人,这是个锤子的状态机哦,这就是个if else

这就是个if else,状态机的本质就是switch case,就是 if else,除非,给他一个结构化的设计。

当你的逻辑状态只有两三个的时候,if else,未尝不可。然后我们来把他结构化一下吧。

看看结构化之后的代码



我们抽象出一个表达状态的接口,于是主要的代码变得非常简洁,这就是一个状态机咯。

不过实现代码就不那么简洁了



有这样的设计作为基础,添加再多的状态也不怕啦,不过这也只是一个解释用的代码。

实际操作时肯定比这个面对的问题要更复杂一些。
2015-11-11 09:42:40  
 赞 赞 1

使用道具 登录

15个回答,把该问题分享到群,邀请大神一起回答。
2#
支持一下
回复 收起回复
2015-11-11 10:47:29   回复
 赞 赞 1

使用道具 登录

3#
立刻提起了精神。
回复 收起回复
2015-11-11 11:35:05   回复
 赞 赞 1

使用道具 登录

4#
立刻提起了精神。
回复 收起回复
2015-11-11 12:35:05   回复
 赞 赞 1

使用道具 登录

5#
想要成大触,天天上元素!
回复 收起回复
2015-11-11 18:44:52   回复
 赞 赞 1

使用道具 登录

6#
不错不错
回复 收起回复
2015-11-12 09:08:13   回复
 赞 赞 1

使用道具 登录

7#
{:1_144:}
回复 收起回复
2015-11-12 09:16:16   回复
 赞 赞 1

使用道具 登录

8#
资源发布哪家强?元素首发称大王!
回复 收起回复
2015-11-12 12:00:57   回复
 赞 赞 1

使用道具 登录

9#
看起来很不错哦,收藏之~~~ 谢谢LZ啦!!!
回复 收起回复
2015-11-13 23:24:44   回复
 赞 赞 1

使用道具 登录

10#
谢谢分享,学习了。
回复 收起回复
2017-2-28 15:37:33   回复
 赞 赞 1

使用道具 登录

11#
不错,理解渗透
回复 收起回复
2017-3-23 15:42:52   回复
 赞 赞 1

使用道具 登录

12#
我为了元素币,也试试,感谢
回复 收起回复
2018-10-20 10:04:53   回复
 赞 赞 1

使用道具 登录

13#
好东西~多谢分享~!
回复 收起回复
2018-10-21 14:26:12   回复
 赞 赞 1

使用道具 登录

14#
感谢楼主分享
回复 收起回复
2018-10-21 14:39:02   回复
 赞 赞 1

使用道具 登录

15#
感谢你的分享
回复 收起回复
2018-10-22 14:10:30   回复
 赞 赞 1

使用道具 登录

16#
666
回复 收起回复
2018-10-30 08:36:45   回复
 赞 赞 1

使用道具 登录

CG 游戏行业专业问题

Unity3D技术手机游戏引擎手游引擎
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表