在上一篇的内容里,我们谈到了UE的3D游戏世界是由Object->Actor+Component->Level->World->WorldContext->GameInstance->Engine来逐渐层层构建而成的。那么从这下半章节开始,我们就将要开始逐一分析,UE是如何在每一个对象层次上表达游戏逻辑的。和分析对象节点树一样,我们也将采用自底向上的方法,从最原始简单的对象开始。

首先需要明确的是,本部分接下来要讲述的UE的GamePlay逻辑框架部分,只是讨论UE的设计思想和理念,并不是表示其在所有其他游戏引擎中是最优最完美的方案,同时当然也不是开发人员务必遵守的金科玉律,你依然可以也应该根据自己实际情况灵活变通。UE经过了很多权衡设计和历史进化,最后选择了该设计方案,一方面和对象层级相辅相成,另一方面也提供了足够的自由度可以供你腾挪。
实现一个游戏业务功能的方式有多种,你应该尽量妥善的权衡你当前的现实情况,考虑生产效率、维护性、功能实现、易理解、性能等等多种因素,然后选择你认为最恰当的方式。如果你当前在制作一个快速原型Demo,你大可以简单粗暴,我也不赞成时刻谨遵教条主义一定要分层拆分如何如何;而如果是面对一个正式的比较大型项目,随着规模的扩大,我们就得利用清晰的概念来帮助我们减轻心智负担。UE作为一个老牌的经历了十几年风风雨雨的游戏引擎,也当然有它的一套GamePlay哲学。我们选择了UE,接受了在UE的工作流之下工作,如果我们能比较好的理解它的概念和思想,就能更加的“顺”着它的思路,得心应手海阔任鱼跃。而如果我们“逆”着这个框架来搞自己的一套,一是不免有无法充分利用UE的嫌疑,二也是以UE的庞大和根深错节难免让你碰一头灰费力不讨好。

Note1:虽然本部分会涉及到游戏的业务逻辑编写部分,但并不打算详细讨论AI(BehaviorTree,Navigation等)。AI也是一个很大的话题,值得专门开个大章节讨论,我们现在不应该委屈她。
Note2:本部分也不会细讨论输入事件的处理,游戏逻辑确实一大部分是由输入事件驱动起来的,不过我们此时只是简单聊一下概念,后续会有章节再细讨论输入事件的路由流程。
Note3:联机游戏的游戏逻辑自然也是非常重要的,但为了简化本章节的概念,所以网络联机的逻辑同步等也都不会涉及。留待后续网络章节再好好的阐述。

Component

Actor可以说是由Component组成的,所以Component其实是我们对象树里最底层的员工了。在UE里,Component表达的是“功能”的概念。比如说你要实现一个可以响应的WASD移动的功能,或者是VR里抓取的功能,甚至是嵌套另一个Actor的功能,这些都是一个个组件。正确理解“功能”和“游戏业务逻辑”的区分是理解Component的关键要点。
所以我们在这一个层级上要编写的逻辑,是实现一个个“与特定游戏无关”的功能。理想情况下,等你的一个游戏完成,你那些已经实现完成的Components是可以无痛迁移到下一个游戏中用的。换言之,一旦你发现你在Component中含有游戏的业务逻辑代码,这就是所谓的“Bad Smell”了,要警惕游戏架构是否恰当,是否没有很清晰的概念划分。

Actor

如果说UE是一个大国家的话,那Actor无疑就是人口最大的民族了。StaticMeshActor,CameraActor……我们天天口里嚷嚷的也都是它。和Unity的Prefab对应的,在UE里我们用的最多的也是BlueprintActor了,我们也常常自定义我们的Actor子类来组装其他Component和Actor,然后再编写一些协作逻辑代码,就似乎完成了一个骁勇善战的特种兵,接下来就可以撒豆成兵般的往Level中扔了。
用的越广泛越多,往往错的也越多。似乎是受到了一种朴素的子承父业的精神感染,也或许是我们的面向对象编程都学得太好的缘故,我们都非常倾向于直接在Actor里堆砌逻辑。右

网友评论