虚幻4随笔5 使用中的一些发现

时间:2022-04-20 04:01:47

行文匆匆,有些不太明白的地方评论里有补充,现在这里抱歉了!


半年多没有维护博客了,一方面是媳妇怀孕,另一方面是公司年中有一个版本……

最近闲暇时间一直在研究虚幻,目前铺开了大概六七个原型在做,做的过程中学到了不少东西,有一些新的想法。

本来这些都是准备展开来说的,但是现在看来,每个话题展开都是需要大把的精力,所以还是先写到这里。有些已经有一些结论,有些还没有展开研究,就当是挖个坑吧,在后面几个月陆续填。

目前博主所用的版本是4.4,有些结论未必在未来还继续有效,如果发现有变化,后面会单起博客说明的。

 

总论:

仍在发展中,如果是准备用来做短期商业项目的,请合理评估风险。用来进行长期商业项目、或者觉得目前的功能已经可用、或者以研究为目的的,可以考虑介入。

优点是开发架构和框架体系成熟,国内策划不做脚本不做原型的开发模式可能确实相对不易适应。说程序用BP不习惯的恭喜您说出了一句正确的令人发指的废话,BP是设计给策划和关卡设计师用的,不是给你程序员用的——话说回来,也就在中国需要去把策划的想法翻译成代码的程(Fan一声)序(Yi四声)员(Gong一声)。

再次重申,如果您希望什么事儿都是程序给吃下来,或者您的项目*处于这种态势,而不是由策划负责脚本和内容的制作,那么请出门左转,找CE、Unity(大雾)或者其它引擎,虚幻这种跟欧美式开发方式深度绑定的引擎绝对不适合您。相信我,您只是在给自己找麻烦,然后回过头来大骂这是一个垃圾引擎——其实只是您项目的开发模式不是原型开发模式,仅此而已。

没有程序基础的,看几个例子应该也可以自己用BP动手做点原型了,我现在基本主要游戏逻辑都用BP做,C++给BP写节点和第三方库的整合插件。BP用熟悉了,比手写代码的开发效率高多了(编译和部署时间、调试更直观方便、而且本身拖图的效率就不比手写差太远,有些情况下反而比手写高)。

此外开放代码,比较深坑的地方可以自己修改,也可以随意整合各种C++库进来,许多细节的实现比较有参考意义,比如WeakPtr之类的。论坛里有许多C++库的整合项目的通知,可以随时关注。

缺点是上手需要一定成本,此外,平台上不支持PSV、PS3、Xbox360这些平台,手机平台不完全支持,希望全机种支持的要注意,目前只能考虑Unity或者MonoGame。

升级快一方面也是一种缺点,旧版本还在玩得不亦乐乎,新版本又添了一堆新东西,这不,博主还在头疼于自己扩展的自细分地表渲染插件在4.4下表现超级糟糕的问题,4.5出来直接这个问题没有了……没~有~了~,我那废寝忘食地搞了一个周末是图个啥……图~个~啥~?!……所以,换句话说,专业的事情,交给专业的团队去就好了。重新发明*这种事儿,十年前是时尚,十年后就是愚蠢了。

 

工程部分:

Module不能出现重名。

Build.cs和Build类名必须一致。

可以创建独立的Win32工程了,虚幻3是独立Exe,如果想用到虚幻的功能,要么是需要把虚幻按照dll模式编译加载,要么是整合在整个Launcher里,虚幻4可以创建独立的Win32工程,工程里可以只用到虚幻的某些个子集。具体可参考引擎Solution里的那些Win32工程,此外,早期版Win32的工程设置和后期版的Win32工程设置不完全一样。可根据自己的需要选择最合适的模式。

多个项目间共享的功能,最好建立plugin工程。也可以修改UBT,添加自己的文件夹。

目前没有找到能在独立路径下建立plugin的途径,似乎只能放到项目的Plugins文件夹里或者引擎Source下的Plugins文件夹里。

发布Plugin给发布版用,4.3似乎是需要先找到发布版的Version.h文件,用这个文件覆盖对应Release版本Git库中的对应文件,然后再编译和发布Release。

所有虚幻的Plugin是有加载顺序的,有依赖关系的插件要注意,可以通过设定Plugin的加载阶段和Dependency来解决这个问题。

一个工程(Plugin或者游戏工程)里可以包括多个模块(Module),注意最好把核心部分和编辑器部分分开,否则发布游戏时发现依赖了一堆不需要的库,太浪费了。可以理解Plugin和工程是一个打包单元,但Module是一个组织单元。

 

Object Core

反射实现很经典,不一定优美,但是很实用。博主之前试图实现过一个C++版的反射,template绝对用得比它好(从boost mpl继承过来的),就是因为缺了它那个分析代码得到Meta数据的东西,导致维护Meta起来太复杂了……再次说明牛逼的技术不是在那里玩技术玩语法,而是在玩工作流……

类和模块改名了,导致之前做的资源失效?Config文件中的redirector可以帮助你。

但不是万能的,BP重命名要小心,似乎BP类名改过来了,但是里面的内容没有改过来……

资源更换文件夹后,本地仍然留有一个1k左右的"尾巴"?这也是redirector的"功劳"。请使用fix up清理。

虚幻的各个Ptr的实现很精彩。RefCount对象可走SharedPtr,此外还有WeakPtr等。

官方推荐琐碎而单位时间比较小的异步功能,可以考虑TaskGraph。时间较长的异步功能可以自己写Runnable。TaskGraph还没太搞明白怎么回事。

 

Actor - Component

Movement拆出去了,UE3的Movement是整合在Actor体系内的,重新实现不同的Movement会比较费劲。现在好了,重新做一新的Movement就好,还可以在不同的工程之间重用。

Component具有父子关系了!不仅仅是SkeletalMesh对其它Component的父子关系,其它所有的Component都有父子关系了。

Actor的Tick貌似现在是多线程了,具体还没有跟。

 

Player – Controller

输入现在多了一个InputComponent,输入消息由Controller截获后,有可能会先发给激活的Pawn的InputComponent和其它InputComponent。可以运行时动态切换输入所操控的对象。UE3只能由PlayerController发布所有的指令消息。

Component挂接,UE3的Attach/Detach已经改名为Register/Unregister,在Register之前,需要先把root设置好。与UE3稍微有点不太一样的是,Actor没有显式Register接口(FinishAndRegister做了一些附加的逻辑,调用前需要先评估是不是自己需要的),Register All什么的在Component数量多的时候非常昂贵。目前对部分Component的Register操作,经实验是可以使用的。

 

渲染核心

Renderer现在有两个:ForwardShadingRenderer和DeferredShadingRenderer,4.5的变化还未跟踪。

默认是不开远裁剪面的,如有需求得自己主动在View里面设置远裁剪面。

虽然多线程的调用型改了,但主体流程与UE3的渲染线程模型基本没有变化,UE3的所有渲染扩展方式,仍然基本可用,主要需要注意的是对其他设备的向下兼容性(主要关注Shader里的那些宏即可)。

 

Blueprint

目前主要用来开发原型,几个版本的细节修改还是挺多的。

总而言之,首先需要提醒的是,用BP做项目,目前一定要记得多备份,最好自己架SVN服务器,改一点测一下就上传一次,特别是跟接口和改名相关的场合。博主为此浪费了两天左右的时间。

目前Blueprint创建的Actor基类,其基类中指定的Component是无法被子类修改的,而且其属性无法直接作为Actor的参数来修改。解决方法是在Actor中增加对应属性,并在Construct图中,修正Actor的对应属性。

不带函数返回值的BP函数,重载时需要在Event Graph里进行操作。带函数返回值的BP函数,则是右键重载。修改函数原型时,要注意有可能会发生修改前是个右键函数重载,修改后是个Event图重载。

修改与BP合作的Interface调用型的时候,BP的重载实现有可能会发生找不到或是其他情况,要小心,改之前记得备份。

全局方法和静态方法怎么办?可以做到BPFunctionLibrary里。

读表虽然有DataTable什么的支持,但需要代码介入,感觉不是很舒服,推荐自己整合读表、读文件功能到BP中,一劳永逸,代码可以参考它Json解析和Csv解析部分。

 

UI

类似WPF,熟悉WPF的人应该非常容易上手,数据绑定什么的基本都是WPF那套概念,对我这种WPF的铁杆支持者简直是如沐甘露。数据绑定也是那种上手很困难,但一旦上手就觉得其它所有UI系统都好Low啊这样的东西……当然,这玩意儿对性能的负面影响也是客观存在的。一定程度下,性能跟系统的扩展和方便程度成反比,永远不要想着鱼与熊掌都能兼得,要能的话,早有人做出来了。

并非唯一选择,Coherent UI什么的也有插件提供了,而且Coherent也支持Unity和CE3,商业项目可以考虑。