游戏架构核心技术与面试精粹(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-15 16:40:52

点击下载

作者:樊松阳

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

游戏架构核心技术与面试精粹

游戏架构核心技术与面试精粹试读:

前言

这是一本面向游戏开发者的进阶指南。

本书从日常开发遇到的问题入手,以编程思想为线索,探讨合理的解决方案。在技术方面,本书会结合使用广泛的Unity 3D进行讲解。虽然本书中的很多内容都不会被引擎所桎梏,但从某种意义上讲,这确实是一本对Unity 3D使用者有更大价值的书。

为了更便于查找,本书内容组织上采用问答的形式。提出的问题通常都是开放性的,随着对底层原理认识的加深,读者自己也能答出更多有料的内容。当然,作者也会被自身能力限制,所以答案是探讨式的,以期逐步深入地挖掘原理。

本书整体通过以下五个方向组织内容:架构与封装、艺术资源、底层核心、自定义扩展和独立游戏。从层次上看是从应用层、效果层、引擎层、工具层到职能扩展层的顺序论述。大体看来,是从日常技能逐渐过渡到核心能力的讲解顺序。

每个方向围绕一个问题展开论述,有的内容会侧重概念的讲解,大多数情况下会结合实际代码来说明。通过这样的方式,尽量让读者知其然并知其所以然。很多小结后面会有延伸思考,我也希望读者能根据问题深入探讨,这些问题大多附有解答思路,希望能帮助大家养成勤于思考的习惯。

对于游戏来说,技术只是其中的重要部分,但我更将其看作技术与艺术的结合体,因此美术方面的知识、游戏玩法的设计也不可或缺。本书在编排的过程中,我尽量兼顾上述要点,以期有兴趣的新手读者,从业人员,或者是独立开发者,都能从本书中得到些收获。另外,对于希望进入游戏界的读者,本书可以从全局的角度,帮助你理解游戏开发的架构流程。

本书中会将一些网址,或者一些扩展问题的解答放到我的微信公众号中,通过在公众号中回复相应的关键字来获得自动回复。采用这种做法主要基于以下原因:

◎链接很容易更新或失效。

◎手动输入链接比较麻烦,通过微信电脑端可以直接在PC上打开有效的链接。

◎有链接形式的引用知识,方便跳转阅读。

◎对照问题答案时,避免来回翻页。

在本书中,我会以[:回复关键字]来标注某些特殊的内容,通过在微信中回复关键字可以得到相关信息。

下面是我的微信公众号,可扫码加入。

本书前四部分讨论的问题都可以用来做面试题,面试时也可以延伸出很多扩展问题。希望读者能勤于思考,动手实践,“纸上得来终觉浅,绝知此事要躬行”。

资源引用

本书引用的资源基本出自AssetStore中,可以免费下载完整版。我对其中的一些资源做了整合,如果希望下载这些挑拣过后的资源,可以直接下载随书的代码工程,地址为[:mygit]。前面的标记表示,在我的微信公众号中回复mygit即可获得相关内容,以防链接失效。下面介绍这些资源的出处。

2D platformer

Unity官方的2D示例,AssetStore的链接为http://u3d.as/5m5。在这个项目中可以看到2D帧动画的制作方法,其中包含了一个可运行的游戏。

2D Roguelike

一个2D像素风格的项目,AssetStore链接为http://u3d.as/bAx。这个项目展示了如何使用序列帧制作游戏。

Unity-Chan

Unity日本公司提供的Unity资源,AssetStore链接为http://u3d.as/85c。它包含一个动漫少女的模型和动画。截至本书出版,它仍是目前AssetStore中,品质数一数二的美术资源。资源的材质包含了目前主流的卡通渲染技术,在日渐火爆的二次元环境下,这个免费样例极具参考价值。

但需要注意的是,这个角色受到 Unity-Chan License Terms 证书的保护,如果需要在商业产品中使用该资源,需要在显眼处标记UnityChan公司的标志。

Space Robot Kyle

这是一个Unity官方推出的机器人模型,AssetStore链接为http://u3d.as/3t7。整个项目十分简单,只有模型、Diffuse贴图、Normal贴图和标准Lambert材质。由于它效果不错,又是很早就出现的Unity官方资源,因此在AssetStore中,大量插件都使用它作为功能演示模型。读者服务

轻松注册成为博文视点社区用户(www.broadview.com.cn),扫码直达本书页面。

◎提交勘误:您对书中内容的修改意见可在提交勘误处提交,若被采纳,将获赠博文视点社区积分(在您购买电子书时,积分可用来抵扣相应金额)。

◎交流互动:在页面下方读者评论处留下您的疑问或观点,与我们和其他读者一同学习交流。

页面入口:http://www.broadview.com.cn/34236第一部分架构与封装

在开发游戏玩法时,我们常会遇到多变的需求,有些是显示层面的,有些则是深层的游戏机制。

在第1章,我们探讨UI事件使用方式及底层原理,也会谈到搭建框架的技巧。

玩法是游戏的灵魂。在第2章,我们将从游戏循环、时间线、动画事件、同步等多个方面来梳理玩法的要点。

在第3章,我们将讨论游戏中的辅助系统,并分析它们的作用。第1章UI交互

除去《纪念碑谷》这种凤毛麟角的无UI游戏,大多数游戏都需要有UI交互,甚至一些卡牌游戏就是UI游戏,因此开发UI的时间占比很大。

要认清一点,UI本身并没有贵贱之分,只是太多的烂设计毁了它的一世清白。“包围效应”就是其中一例。这种设计常见于依靠复杂系统支持的游戏:“我不需要你玩游戏,我只需要你点点点”。在屏幕四周摆满了花花绿绿的图标,使得原本就很小的屏幕变得更加捉襟见肘,配上令人抓狂的红点,足以把任何正常人的理智消磨殆尽,从而稀里糊涂地点下这些凌乱图标中最显眼的充值按钮。

在国内游戏市场中,这种游戏遍地开花。而在这些以数值为核心的游戏中,UI肩负着信息展示与交互的重任。因此,制作UI是游戏从业者的必备技能。另一方面,这部分通常比较容易模块化,而且大多能跨项目复用,所以也具备深入讨论的价值。

本章依托于UGUI,主要探讨使用UI控件传递事件的相关问题。1.1 绑定事件响应

请列出为UI控件绑定事件响应的方法,并分析不同方法之间的优劣。

问题分析

面对问题时,最重要的是确定它的边界。对于这个问题,如何绑定当然是关键,但UI控件的范围也很重要。不是所有的UI控件都能绑定事件,但能绑定的也不是只有按钮,至少还应包含:

◎拖动条

◎输入框

◎开关

◎滚动区域

当然还有千千万万我们实际工作中用到的自扩展控件。这里不受限于按钮的点击事件,我们用按钮、开关、拖动条三种控件来举例说明。

搭建测试环境

在面临一个新问题时,我们通常会在一个独立的场景中搭建测试环境,来快速验证我们的逻辑是否正确。

在这个例子中,我们要在界面中创建三个控件,并摆放到屏幕的中心。创建方法是用右键快捷菜单添加各种控件,相信大家都知道如何操作。如果不熟悉,也可以通过网络很容易地查到。类似的基础操作不是本书的重点,因此针对此类情况,后文大多一笔带过。创建好的界面大概如图1.1所示。图1.1

接着,编写处理函数。在Unity中,创建名为TestEvent.cs的代码文件,并在场景中创建一个空的GameObject,将TestEvent脚本挂载到GameObject上。打开

TestEvent.cs,输入如下代码:

现在我们已经配置好了测试环境,接下来就看看如何绑定响应。

绑定响应

从操作层面看,绑定响应的方式有两种,但它们的核心是相同的。

1)组件中添加

在Inspector界面中,可以直接在组件中通过拖曳的方式完成绑定。我们以Button控件为例,演示如何操作。

首先创建一个空的GameObject,命名为MyTrigger,在它上面挂载刚刚创建的TestEvent脚本。

完成上述步骤后,在Hierarchy面板中选中Button,然后在Inspector面板中找到Button组件。不难发现在组件的下方有个区域名为OnClick,单击这个区域下方的“+”,就可以添加一个点击事件的处理设置,效果如图1.2所示。图1.2

然后将刚刚含有TestEvent脚本的GameObject拖到下方的“None(Object)”中。操作完成后,单击右侧的“No Function”按钮,在下拉菜单中找到TestEvent.OnBtnClick。操作成功,效果如图1.3所示。图1.3

单击“Runtime Only”按钮进行测试,即可发现在Console中可以输出“Btn Click”。

用相同的方式,可以为Toggle和Slider添加相同的事件处理。添加好后,运行游戏,分别测试控件响应,控制台输出如图1.4所示。图1.4

2)代码中添加

代码添加的方式要简单得多,打开TestEvent脚本,在类中添加如下代码:

然后在Inspector中将三个控件分别拖到脚本的对应位置上即可。

优劣比较

以笔者的经验来看,绝大多数程序员喜欢用代码添加的方式。

一般来说,程序员不会轻易动别人的代码,但预设很可能被其他人更改。当Bug出现时,不使用代码编写绑定,开发人员心里就很没底,无法确认是否是自己的原因。

笔者认为如果有很好的框架支撑,编辑器设置绑定的方式也是可取的。就好像没人质疑在Unity 3D中,Start函数是否会在一开始调用一样。如果有一目了然的绑定显示,并且有稳固的框架支撑,那么在编辑器中绑定也没什么不好。在编辑器中绑定有个优势,就是支持动态更新。由于绑定关系存储在预设中,因此意味着整个逻辑可以跟随AssetBundle更新。如果C#代码逻辑写错了,只更新预设也是白费力气,但可以在基类里提供一个默认的出错处理,以便最大限度地降低影响。

总结

绑定响应的方式有两种;在组件中添加和在代码中添加。它们的核心相同,都是通过代理来回调自己的函数。组件绑定的操作更友好,但容易被人更改。代码绑定的优点是更稳定,而且能更灵活地控制监听的时间点,缺点是逻辑编译在代码中,最好有健全的框架支持,以防止出现使用问题。例如,重复绑定的处理函数,忘记移除的绑定,等等。

扩展问题(1)有没有办法克服代码绑定的缺点?(2)既然大家都倾向于使用代码绑定,那么组件绑定的存在有意义吗?1.2 事件传递流程

请从结构的角度概述,控件的消息模型包含哪些部分,并解释UGUI中点击事件与响应调用是如何关联在一起的。

问题分析

很多Unity 3D项目都使用了UGUI,但并不是所有人都研究过它的内部结构。针对事件的传递过程,会问住大多数未深入思考过的开发者。由于UGUI是开源的,所以我们可以通过查看源码来熟悉它的原理,它的地址在[:uisource]可以找到(前面的标记表示,在我的微信公众号中回复uisource可获得相关内容,主要是担心链接失效)。

事件体系

首先说明,事件体系的基础是设计模式中的观察者模式,因此按照标准的Subject和Observer来解读没有任何问题。但在这里,笔者更希望以功能为导向,将事件体系划分成更易于理解的模块。按这种划分方式,事件体系由四部分组成,分别是:

◎监测器(Monito)

◎采集器(Collector)

◎派发器(Dispatcher)

◎响应器(Receiver)

这四个模块大致的依赖关系如图1.5所示。图1.5

其中用户的操作被监测器驱动的采集器捕获,接着监测器将反馈的信息通知到派发器中,最后通过派发器将事件传播出去。

Unity 3D 实现

在Unity 3D中,功能模块的每个部分都有对应的实现类。

◎监测器(Monitor)对应的实现类为EventSystem。它重写了MonoBehavior的Update方法,会在每一帧更新挂载在同一个GameObject上的采集器组件状态,并判断是否应该激活派发器。如果是,则调用各个派发器中的派发函数Process。

◎采集器(Collector)由两部分组成,对应的实现类分别为 BaseInputModule 和BaseRaycaster,在 UGUI 中默认使用的是它们的子类 StandaloneInputModule 和GraphicRaycaster。当用户操作时,会先由BaseInputModule激活模块,然后发出一个射线点触,返回在BaseRayCaster中能点到的物体并返回信息,交由派发器进行过滤。所以采集器有两端,连接它们要靠EventSystem。整个过程中还有一个静态内部的管理类RaycasterManager,用来做连接采集器和监测器的数据桥梁。

◎派发器(Dispatcher)对应的实现类也为BaseInputModule,最常用的是它的子类StandaloneInputMoudle,该类的角色与采集器混在了一起。派发器完成了实际的事件生成,包括且不限于:事件类型的确定、事件内容的提取、派发对象的过滤。其中对派发对象的获取需要借助采集器,但需要通过监测器来驱动。这种设计可以带来效率上的优势,即可以合并采集操作,以达到降低事件频率的目的。

◎响应器(Receiver)对应的实现类为IEventSystemHandler及其子类,例如最常用的IPointerClickHandler,它的作用是处理点击事件。通过ExecuteEvents类,可以将发生事件的对象上的所有响应器都获取到并调用其响应逻辑。以点击为例,事件最终会被派发到OnClick的代理上,完成逻辑的执行。

类图

相关实现类有好多,大体分两部分,一部分是功能类,另一部分是编辑器类。

功能类按照前面介绍的事件体系可以清晰地找到重要的基类,它们的UML图如图1.6 ([:msgclass])所示。图1.6

这个图只是和点击相关的部分,当然还有很多其他的功能,例如拖曳、滑动等。如果能找到这些重点,其他逻辑就可以结合代码自行推导了。

另一类是编辑器类,这个比较简单,本书没有单独梳理类图,直接用VS自动生成的类图就够用了,如图1.7所示。图1.7

值得一提的是,UGUI的编辑器界面做得很细致,用起来也很方便。当我们需要自定义Inspector界面时,编辑器代码中的一些功能的实现具有参考价值。

总结

如果还是对点击事件的流程不是很清楚,则可以参笔者绘制的按钮点击消息传递的调用流程,具体如图1.8所示([:msgflow])。图1.8

扩展问题(1)请结合设计模式中的观察者模式,分析Unity事件框架的优劣。(2)如何利用EventSystem来降低事件的频率([:eventrate])?1.3 事件响应接口

通常对于事件传递,绑定消息处理时都要写很多相同的框架级别方法,例如:

请问是否有方法对其简化,减轻开发编码量?

问题分析

这个问题并不难。但很多时候,并没有想过从框架层解决冗余代码。这个问题有时也会换个更开放的方法来问:“说说你的UI框架吧。”具体落实到代码上,回答它的重点跟这个问题有很大的重合性。

我们都知道,编程时有个DRY原则,即“Don't Repeat Yourself”。它主张不要编写重复的代码。落实到实际,就是避免在代码中无脑地复制粘贴。

在《重构:改善既有代码的设计》中,不合理的代码结构被称为“代码的坏味道”,破坏DRY原则就很难写出高质量的代码。如何去除代码中的“坏味道”,在这个问题中能得到很好的体现。

添加分层

很多年以前,计算机领域的先驱,David Wheeler就提出过这样的说法:“计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决”

针对这个问题,我们也可以将分层作为突破点。在现有的基础上添加一层,是最容易完成需求的做法。

按照这样的思路,我们需要创建一个容器类,它可以自动将可响应事件的子节点找到,并为其添加监听。代码大概是这样:

然后在新场景中创建一个挂载这个脚本的节点。创建好后再为其添加三个按钮子节点。直接运行游戏,单击按钮即可看到输出,如图1.9所示。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载