辛巴学院-Unity-剑英的c#提高篇(一)主循环
这是测试版
辛巴学院:正大光明的不务正业。

最近刚刚离开了我服务了三年多的公司,因为一个无数次碰到的老问题,没钱了。
之前不知道做什么好的时候,机缘巧合之下和哒嗒网络的吴总聊了一下,发现了vr game这扇窗户,这里权当帮哒嗒网络打个广告吧。^_^
回头看看仓惶的这一段时间,荒废了很多,抽空回来再和大家聊聊c#。
之前做了个入门系列,胡乱说了些东西。感觉入门这样子也就差不多了,该稍微提高一点了。
从写一段程序,到写一个app,写一个游戏,到底其中有什么不同呢?一段程序的执行时间很短,一个应用的执行时间很长,仅此而已。
游戏中存在一个帧的概念。

这个概念大家都知道,类比的话,它就是电影胶卷的格。一格出现一段时间,然后换下一格。
电影一秒24格,游戏用的是一秒30帧,60帧。
电影胶片是在镜头前一格一格的放映,游戏逻辑是在update中一帧一帧的执行。
那么Update函数的驱动是如何完成的呢?
这个东西就是主循环
先来看看一个基本的控制台程序

唔,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,未尝不可。然后我们来把他结构化一下吧。
看看结构化之后的代码

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

有这样的设计作为基础,添加再多的状态也不怕啦,不过这也只是一个解释用的代码。
实际操作时肯定比这个面对的问题要更复杂一些。
再会,哈库拉玛塔塔
辛巴学院-Unity-剑英的c#提高篇(一)主循环的更多相关文章
- 辛巴学院-Unity-剑英陪你零基础学c#系列(一)Hello World
这不是草稿 辛巴学院:正大光明的不务正业.辛巴学院:攻城狮与荣耀石. 剑英陪你系列又来啦.剑英是一个有大爱的人,热爱每一个程序员,尤其是年轻漂亮的女程序.最近组织朋友们玩了一次即兴团体诗创作,无论怎么 ...
- 辛巴学院-Unity-剑英陪你零基础学c#系列(四)函数和封装
辛巴学院:正大光明的不务正业. 国庆长假结束了,我的心情是这样的: 你总是起不早,起不早独自一个人沉睡到天亮你无怨无悔的梦着那副本我知道你根本就不想上班你总是起不早,起不早放假总是短暂,上班太难请个病 ...
- 辛巴学院-Unity-剑英陪你零基础学c#系列(三)计算与类型
辛巴学院:正大光明的不务正业. 中秋节快乐,每逢佳节倍思亲,尤其是那素未谋面的老婆,对吧,屌丝们. 今天我们来探索一下C#里面奇怪的计算,奇怪的类型. 奇怪的计算 当我刚刚接触计算机编程的时候,一 ...
- 辛巴学院-Unity-剑英陪你零基础学c#系列(二)顺序
这不是草稿 辛巴学院:正大光明的不务正业. 上一次的教程写出来之后,反馈还是挺多的,有很多都做了修改,也有一些让人崩溃,不得不说上几句.有些人有些很奇怪的地方,你写篇东西,被看了以后不说他感觉怎么 ...
- (转载)李剑英的CSLight入门指南结合NGUI热更新
原地址:http://www.xuanyusong.com/archives/3075 李剑英的CSLight入门指南文档撰写者:GraphicQQ: 1065147807 一. CSLIGHT 作者 ...
- 辛巴达:帮电商打造ZARA式开放供应链体系 - 行业网站 - 亿邦动力网
辛巴达:帮电商打造ZARA式开放供应链体系 - 行业网站 - 亿邦动力网 辛巴达:帮电商打造ZARA式开放供应链体系
- 剑英陪你玩转图形学(五)focus
很久没来和大家交流业务(zhuangbi)水平了,最近实在是很忙,报名了小游戏大赛,一点时间都抽不出,已经坑了. 今天抓紧时间和大家介绍一个小效果: 新手引导的时候,我们会需要一种全屏幕黑掉,只有一个 ...
- Unity笔记 英保通 Unity新的动画系统Mecanim
Mecanim动画系统是Unity独一无二.强大灵活的人物动画系统.该系统赋予您的人类和非人类人物令人难以置信的自然流畅的动作,使它们栩栩如生.游戏中角色设计提高到了新的层次,在处理人类动画角色中可以 ...
- Unity 之 Redux 模式(第一篇)—— 人物移动
作者:软件猫 日期:2016年12月6日 转载请注明出处:http://www.cnblogs.com/softcat/p/6135195.html 在朋友的怂恿下,终于开始学 Unity 了,于是有 ...
随机推荐
- Ubuntu下配置python完成爬虫任务(笔记一)
Ubuntu下配置python完成爬虫任务(笔记一) 目标: 作为一个.NET汪,是时候去学习一下Linux下的操作了.为此选择了python来边学习Linux,边学python,熟能生巧嘛. 前期目 ...
- 动态更换应用Icon
转:原理1--activity-alias 在AndroidMainifest中,有两个属性: // 决定应用程序最先启动的Activity android.intent.action.MAIN // ...
- echarts之tooltip-position
当postion为Array时 tooltip : { trigger: 'axis', position:[3,3] //赋予一个[x,y]的位置 } 当postion为function时 tool ...
- spring spring data jpa save操作事务
整合spring spring data jpa的时候,在save方法上加了@Transactional注解.此时调用springdatajpa save方法并不会真的把数据提交给数据库,而是缓存起来 ...
- Redis——学习之路二(初识redis服务器命令)
上一章我们已经知道了如果启动redis服务器,现在我们来学习一下,以及如何用客户端连接服务器.接下来我们来学习一下查看操作服务器的命令. 服务器命令: 1.info——当前redis服务器信息 s ...
- win下安装jdk7后,修改环境变量无法改为jdk6的问题
jdk的安装包,现在的策略改变了,不再帮你设置环境变量,而是直接把java.exe,javaw.exe,javaws.exe直接拷贝到了system32下. 删掉这3个,path就生效了!
- JS冒泡排序(div)
更生动的排序动画. 通过改变div的高度来实现排序,通过闭包来实现for循环的睡眠时间. <!doctype html> <html lang="en"> ...
- requirejs 打包 添加版本号收集资料 待测试
https://www.npmjs.org/package/rjs-optimhttps://www.npmjs.org/package/grunt-requirejs-md5指定js版本号 但不是M ...
- 在Andoid开发中使用MVP模式来解耦,增加可测试性
by Jeff Angelini posted on 7/20/2011 2:35:00 PM 将应用程序UI的表现从Ui的逻辑中分离是一个好的想法.这种分离减少了代码耦合,代码更加干净, 甚至可以有 ...
- 使用spring的@Scheduled注解执行定时任务,启动项目不输出警告
在applicationContext.xml中添加: xmlns:task="http://www.springframework.org/schema/task" xsi:sc ...