查看: 509|回复: 5

虚幻4随笔

[复制链接]

1

主题

342

帖子

7万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
75866
发表于 2015-9-30 21:31:12 | 显示全部楼层 |阅读模式




从3月份就开始断断续续写的,前段时间比较忙没有坚持,慢慢准备写一个系列。
主要瞄准的是使用过程中发现的UE的一些内部实现细节,先把之前的这一批给搬运过来。
欢迎大家多拍砖。
http://blog.csdn.net/noslopforever/article/details/40296705
最近闲暇时间一直在研究虚幻,目前铺开了大概六七个原型在做,做的过程中学到了不少东西,有一些新的想法。
本来这些都是准备展开来说的,但是现在看来,每个话题展开都是需要大把的精力,所以还是先写到这里。有些已经有一些结论,有些还没有展开研究,就当是挖个坑吧,在后面几个月陆续填。
目前博主所用的版本是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,商业项目可以考虑。
------------------------------------------------------------------------------------------------------------------------------------------------------------
早上写的比较匆忙,补充几点:
1、直接包含Windows和第三方头文件有时候会发生DWORD什么的错误,这种情况下,把这些头文件和用到DWORD什么的地方,前面后面分别包含AllowWindowsPlatformTypes.h
和HideWindowsPlatformTypes.h即可。
2、Redirector是一个特殊资源,在编辑器里是可以看到的,方法是在Content Browser里面Filter- Misc- Redirector即可。一旦清除成功,Redirector会自动消失,否则右键可以选择查看Redirector的引用。Fix up的时候,可以用这种方法针对单一Redirector进行Fix,也可以在Content Browser左侧文件树右键选择Fix up redirectors,但是后者在具有跨地图引用时不能保证真正干净地清除redirector。
3、Player Controller,对于Pawn及其派生类,应使用Prossess节点来将输入定位到对应的Pawn。而如果是普通的,内部带InputComponent的Actor,则应该使用EnableInput节点。此外,对Controller自己使用EnableInput是可以临时屏蔽本Controller的所有输入的。BP里默认是不提供在多个Controller中切换的方法的,如果需要需要自己把相关类和方法封装。
4、InputComponent是不需要手动挂接的,只要在BP的EventGraph里面进行了输入类的Event侦听,就会自动挂接InputComponent。
5、BP函数的返回值,如果有那种这个场合返回这些,那个场合返回那些的情况的话,可用Local Variable来解决这个问题。顾名思义,Local Variable是每个函数有各自的,不会互相冲突。6、Component Register有不少网友表示写的不清楚,抱歉。那里的意思是,Actor的Register相关方法里比Component本身的Register多做了一些工作,看似主要是Navigation方面的。目前对主要的图元Component做了一些测试,本身单独调用Component的Register是可以正常看到的,但是会不会有风险还不太清楚。Actor身上挂太多Component的情况下,Reregister一次会很慢。
目前就想到这么多,有看不明白的地方还请指出。
http://blog.csdn.net/noslopforever/article/details/21936539
打开UE4,短暂的兴奋过后,开始大概扫一扫UE4的编辑器,整个界面比UE3更有现代气息:
之前看其他人写的文章,虚幻4最重要的改动集中在下面几个方向上:
跨平台:
WIN和MAC平台都能使用,这就意味着必须使用两个平台都能接受的方案。
界面:
由于上述的原则,WPF界面虽然很酷,不支持MONO就只能跟好评无缘了(顺便吐槽一下微软,基于NET做了那么多东西,却总是虎头蛇尾)。因此虚幻这回是自己搞了个界面操作系统出来……而且更丧心病狂的是这个界面可以用在游戏里……
C++化:
不知道是因为Unreal Script在移动平台上的性能表现不给力,还是因为自己维护一套Script成本稍显浪费,无论如何,UE4开始,之前负责连接工具和逻辑、内容提供者和解决方案提供者的Unreal Script让位给了 格式化 的C++。
这个改动并不是孤立的,相应的,整个解决方案更明晰地划分为了核心层、插件、逻辑层,一方面也提高了跨平台方面的能力。
同时,围绕着这个特性,最重要的应该就是热更新功能了吧?逻辑层代码由于已经独立于核心层,所以C++编撰的逻辑层代码修改,不需要退出编辑器,就可以在编辑器中自然而然地编译并重新载入——参与过实际项目的战友们应该都明白这意味着什么。
另一方面来说,国内不少战友拿到这种国外的引擎往往是一种暴殄天物的用法,把这些引擎改得乱七八糟。所以笔者个人感觉Unity重新定义了国内的引擎用法——没代码引擎变相的 好处 ——人们不再是关注与技术细节,而是关注与Workflow了,而后者才是国外引擎现在真正的核心和强大之处。笔者本人现在就深陷于一个由于改造了国外原本优秀引擎而导致满地大坑的项目中……不过想来未来会越来越好——国内的开发者如果现在再准备把引擎改得乱七八糟,是要被策划和美术同学鄙视的——人家本身这么牛逼的特性,你一弄,没了,咋回事儿?给个解释呗?
Blue Print:
其实就是之前的Kismet的强化升级版,UE3单用Kismet能做出游戏,升级版的Blue Print应该只强不差。
UPK:
不见了,资源单文件存储:争议满满的UPK终于离开历史舞台了,所有资源现在以.uassert的后缀名分散在Content文件夹下的各种场合。这也意味着之前资源包升级和DLC最大的一个拦路虎没有了。看Launcher本身就做了自动更新,想来自动更新应该是引擎本身就可以支持了吧?
大概用了用,浏览了一下它的一些例子,感觉都很不错。
如果想开始制作自己的游戏的话最好先看看Content Examples:介绍虚幻4的基本特性和用法。从头到尾浏览一遍基本上这个引擎的使用方法就都清楚了,未来这块儿的工作应该主要是美术和策划的工作,程序大体应该了解一下,特别是如果还没有接触过虚幻的同事们,这个可以让你很快明白虚幻的整个工作流。
基本上,除了蓝图(虚幻3里KISMET的增强版)、地形有些变化外,其它内容部分相对UDK并无太大变化,虚幻3玩家应该能很快就上手。
其他例子多是一些手机版的游戏例子,不过例子不在多在完整。顺便说一句,Strategy Game这个可以关注一下。当年跟很多人争辩说虚幻能用来做RTS没人信,这个例子虽然不完全是一个RTS,但是基本上可以改变 虚幻只能用来做FPS和TPS 的印象了吧?
自己建立一个例子工程,随便找了个Third Person的模板,带BP的模板是指纯Blue Print,不带任何代码的。笔者创建的是带代码的版本
Binaries顾名思义,这个例子最后会生成一个DLL在Binaries里,然后编辑器会重新加载这个DLL。热更新的具体代码还没看,但是应该是这个路数没跑。
Config跟UE3的Config一样,项目级别的操作系统设置,后面详细展开,一般来说,如果要改设置的话是改这里的Config。
Content就是原来UE3的Content,美术、策划资源全在这里,不解释。
DerivedDataCache还不知道是做什么的,后面看看吧。
Intermediate是生成的临时文件,包括工程、中间文件。
Saved包括一些运行时会创建并维护的内容:备份、日志、运行期的Config,跟UE3的方法一样:这个Config不需要去改,改动的应该是根目录Config下的内容。
Source不用说就是代码了。
会自动生成SLN,打开这个SLN就可以开工了,就像Unity会自动帮你建立一个Mono Develop工程一样。

如前所述,虚幻引擎所使用的是C++,而不是C#、Java代码。有人总觉得C++会导致虚幻上手难度变高,笔者个人感觉还好,因为你用到的C++是带有一定限制的,这些C++类是需要考虑与引擎其它部分的关系,以及考虑与编辑器的关系的,再加上虚幻自己实现了垃圾回收,所以整个调用并不会比C#麻烦太多——当然,LINQ什么的特殊语法就罢了。
生成的代码包括:
ThirdPerson:模块文件,似乎是定义这个DLL模块的,追溯了一下感觉像是DLL Entry这样的东西。
ThirdPersonCharacter:第三人称模式下,控制器操作的对象。目前里面写了很多跟输入消息绑定的语句。
ThridPersonGameMode:Game Mode是UE3带过来的概念了,当前第三人称游戏的一些设置,目前这里面定义了当前游戏控制器的操作对象:
  // set default pawn class to our Blueprinted character
static ConstructorHelpers::FObjectFinder UClass PlayerPawnBPClass(TEXT( Class'/Game/Blueprints/MyCharacter.MyCharacter_C' ));
if (PlayerPawnBPClass.Object != NULL)
{
   DefaultPawnClass = PlayerPawnBPClass.Object;
}
注意这里,不是直接注册的ThirdPersonCharacter,那ThirdPersonCharacter还有什么用?
别急,我们先看看:
Class'/Game/Blueprints/MyCharacter.MyCharacter_C'
这个意思是从Content/下的Blueprints里加载MyCharacter.MyCharacter_C,并把它认成一个Class。
我们去资源里找这个BluePrint:

打开:

解释一下就是这个BluePrint是从ThirdPersonCharacter派生的……OMG
所以,写在ThirdPersonCharacter代码里的那些与输入消息的绑定才有用:因为是这个MyCharacter是从这个C++脚本派生的嘛。
但是这么一来,MyCharacter一方面可以集成程序提供的基本操作方案,另一方面,策划可以通过BluePrint为其设计一些特殊的连线流程,两全其美啊!
有些东西,不想给策划弄的,或者策划弄不了的,比如AI底层,程序来集成就好了。想给策划弄的,这么一来你自己Blue Print去吧。
这块儿笔者真心给跪了。Orz
过去的UE3的Kismet也不是不能跟对象一起用,但那如果在编辑器里操作,就是得用Prefab,本身Prefab没有任何跟代码相关的概念,基本类似于一个各种对象放一起的大组。从某类继承?对不起,没这个概念。
所以UE3里,这种情况就得自己用Unreal Script写个UC类,然后在代码里自己手动拼各个组成组件的空间关系……加上Kismet互操作的代码来进行Kismet的互操作。
现在这Blue Print完全超越了Prefab这个概念,相当于把原来Unreal Script的这个工作用图形化的方式接管过来了……难怪Unreal Script被彻底抛弃。


开始运行,享受了一番,在ThirdPersonCharacter的方法里断点调试了一下,与猜测基本无差。
最牛逼的是,我们把代码里Move Right代码注了,

编译,然后再跑,不关编辑器,角色的向右移动就被我们给毙掉了,只能向前冲。
这个过程稍微有点危险,笔者致挂一次,记得保存改动先。
还想继续整整,到上班点了,最近公司工作较忙,只能先放放后面弄了。
笔者现在进行的其实就是UE3以上、UE4未满的工作:策划通过图表完成自己的想法。在一个老企业中推行这种其实已经不算新,但在国内特别是北京圈还不算非常能让人接受的做法。希望这次UE4的出现能让各位大爷们好好冷静下来想想。不要老说 国内这么做游戏是有理由的 ,我想说的是国外的游戏做的比你好,也是有理由的!
http://blog.csdn.net/noslopforever/article/details/21696005
2014年3月19号,也就是中国时间20日凌晨,虚幻4放出了“订阅制”这个重磅炸弹,估计出乎大多数人的想象,已经不止一个同事表示“自己的引擎这下没用了”。
笔者前天搞定了付款,下载,编译和运行。
基本就是只要有一张visa或者MasterCard的信用卡,官网www.unrealengine.com注册一下,填写支付信息,地址什么的随便写个或者硬写中国的地址,然后去github开通一个账号,最后在官网账户设置里把官网账号和这个git账号关联一下,就可以从github下到代码了。
下完后如果短时间内不升级可以考虑退订,这样只是不能更新,没有其他问题。

所以说到时候开通中国区付款后这里取消订阅再重新订阅就好了,办张双币信用卡,不必纠结付费的问题。
下载主要是git代码,30兆左右,然后要按着git页面上的提示(付费后才可见),去release页面下载dependencies包,总共3个:

先解压1of2和2of2,Optional是2012编译所需的,2013可以无视,笔者用的2013 express,就没有试。
最后把解压后的dependencies拷到代码文件夹里即可。

然后运行根目录的bat,即可在根目录生成2013的UE4.sln文件,如果出错,可能是目录没考对,对应提示来看看什么问题就好。
进入后,生成配置选择developer editor就可以开撸了,笔者的Surface Pro用了大概40分钟才撸好,要有心理准备。
如果用的是2013 Express,可能会有个atlbase.h找不到,编译不过的问题,是因为2013本身是不带ATL/MFC的,去官网下个ATL/MFC,然后在工程里设置一下ATL / MFC的头文件和Lib路径即可。
编译完毕后,UE4工程设为启动项目,F5之,启动后可以选择载入一些游戏模板或者建立空场景,这时候可在其他目录里建立游戏相关的工程(游戏工程和引擎工程可以分开了,不需要再像UE3那样绑一起了),默认不选目录的话会在我的文档下开一个Unreal Projects文件夹来存工程。

新建项目

笔者已经建立的项目

项目文件夹,可以跟引擎文件夹分离。
建立工程后会自动打开这个游戏工程的Sln,后面要开工的时候打开这个Sln,运行项目工程(不是UE4)即可,如果不是建立新的工程的话,不需要再打开UE4.sln了。

工程文件夹里会包括一些配置、初始资源、代码以及工程Sln,见上面的项目文件夹图。
MarketPlace里有很多示例:

第一次点击会提示您安装,最好装到个大点的盘,目前发现它这个东西下载时是会写到安装路径下。几个GB的资源,未来有可能更多,小盘的话后面杯具。官网有人发帖表示后面拷贝到新的路径还得重下资源,所以争取一步到位吧。
安装后,第一次要下载更新包更新,这一步看人品,身边有不少人都遇到了卡81的问题:

卡在81这里老半天,最后报个:

官网正在讨论这个的解决方案:
https://answers.unrealengine.com ... on-downloading.html
笔者自己是一直不断关了重开,试了20几回,不知道怎么有一次就好了……所以说很看人品……如果您也遇到了这个问题,可以多试几次,也可以看看上面的链接最新到什么程度了。
(按:可能跟虚幻的下载资源一般都放在亚马逊云有关,亚马逊云在国内似乎经常出这个问题,VPN似乎能好不少)
好了的话,“正版用户”就基本上可以下载了:

这个没节操的……Bird发现!

盗版用户这里怎样我也不清楚,不过这次Epic已经是非常有诚意了,希望大家能支持一下正版,毕竟引擎越做越好用,实际最终受益的是我们所有开发者。
初步感觉变化还是有点大的,后面慢慢展开,希望我能完成这个系列。
http://blog.csdn.net/noslopforever/article/details/22170627
笔者有幸参与过两个UE3项目,完全不同的使用方法,总共用了5、6年。引擎学习最好还是能参与项目,自己看的话往往容易纠结到一些细节上去,而引擎之所以是引擎,重要的恰恰是在容易被人忽视的工作流上。单从细节上看,UE3的代码很多地方并不完美,甚至有些奇怪,但是一旦做到工作流上,就会发现整个UE3工作流的强大之处。
先回顾一下UE3操作系统的一些结构要点,权当做个记录,看看UE4在这些方面有什么不同,作为我们接下来读码的突破口。
如果真心想要学习这个引擎,最好还是能用它来做做项目,项目不分大小,只论完整程度,笔者短时间内看来是没机会了。
1、BuildTools
UE4除了工具和插件外,本体不分工程了,UE3的核心部分最后分了Core、Engine、Editor、WinDrv、Network、Renderer等十数个工程,UE4就一个UE4工程。但工程归工程,编译时还是分得很开的。
而且这个工程猜测是靠BuildTools来生成出来的(一开始那个bat)。看起来,散落在各个文件夹下的.cs文件就像CMakeList.txt那样,它们才是整个工程的组织核心。
事实上从UE3时代,就可以完全脱离Visual Studio IDE来工作了,UE3的工程本身都已经不再是典型的VC工程,代码编完后,实际上最后执行的是Build.bat、调用UnrealBuildTools.exe来编译,所以要改工程设置,也是需要去修改UnrealBuildTools工程的。
** 估计,如果要改工程组织结构,增加文件什么的,也需要维护这个.cs文件吧。这个可能得等做做才知道了。
不过应该可以看出来,UE4这里是为了支持项目和引擎分离而进行的。
2、Core
个人观点,UE3的Core重点是下面几个部分:
作为整个虚幻构架基础的UObject和由一大堆宏和各种Classes.h这套组织结构反射操作系统——围绕它的包括GC、UObject与UnrealScript的互操作性、与编辑器的互操作性、自动序列化、对象克隆等。这个非常重要,整个虚幻体系的核心就是这一套东西,如果前面不注意的话,后面迟早会在这里栽点跟头。
序列化和统一具名访问:ULinkLoader,起这个名字可能主要是因为加载的时候,它会自动分析Object的引用链,并且根据需要继续往下加载。另外,所有虚幻的Object都会有自己独一无二的具名路径,例如xxx.umap:persistentLevel.Pawn_0,xx.Material.Material_0,任何时候,只要使用LoadObject、FindObject并传入这些名字,就可以访问到对应的对象。这个在编辑器的维护中是相当方便的一个底层特性。甚至,这个具名路径还可以访问到脚本中的类、内置模板资源等等。
MakeCommandlet和UC脚本核心:Core中间编码了整个Unreal Script的编译和运行时环境。Unreal Script编译过程中会生成相应工程的Unreal Script/C++互操作文件:xClasses.h以及一堆自动生成的方法和调用。编译后的结果是.u文件,其实同时就是跟.upk资源文件一样的格式——虚幻2不清楚,但至少从虚幻3时代开始,资源和脚本就被当作是同一个东西,脚本是可执行的资源,资源是不可执行的脚本。另外与此相关的就是一套调试器——很多人用了半天虚幻3却不知道虚幻脚本是可以调试的……AutoDebug命令行或者ToggleDebugger指令搜一下,印象中调试器的核心接口是基于UDebuggerCore还是UDebuggerInterface这个类。VS装nFringe插件后、或者自带的UDE都可以对脚本进行调试。
状态机:脚本的特殊语法,状态机是在脚本类内部的概念,每个状态可以重载脚本类某些函数的实现,这样当状态切换到这个状态的时候,就只是执行状态内的函数而非脚本类的函数本身。Actor和Controller里大量用到。
Latent:脚本的特殊语法,基本类似于不通过连线的Kismet,latent类似于Erlang这样的Coroutine中文/外语,每个语句都是步骤而非过程,步骤可能会花很多帧去执行,执行完毕后接着进行下个步骤,传统中文/外语的过程只能当前帧执行完毕。
其它就是一系列的数学库、内存管理、辅助函数。内存管理比较有意思,一开始看总觉得问题较大,当时组里的内存专家Aman Jiang老师实际打出来报告后发现这块儿管的还是很不错的,碎片率远低于我们的预期。
3、Engine
相当庞大的集合,个人观点,重点在于:
Actor-Component体系:组件化结构的虚幻版,组件化现在应该是大多数引擎的标配了吧?这块儿可以说中规中矩,主要组件还是得花心思去看看,否则极易在接口调用顺序乱掉的情况下发生问题。渲染器与游戏上层逻辑通过Component来接口,提供新的渲染技术后,只需要做一个对应的Component就可以了——SpeedTree什么的就是这么集成进来的。
Game-Player-Controller体系:Game Mode决定了当前关卡的游戏玩法,一个关卡可以有不同的游戏玩法——对于FPS你可以想象虚幻竞技场中的很多地图都同时支持Free for all、夺旗、Team计分。对于网络游戏,你可以想象一个关卡资源可以用来做战场、也可以用来做副本。Player是所有IO的总入口,一般一个游戏只有一个Player,就是Local Player。主机游戏可以设计同时存在两个Player的场合,可以用分屏显示来分离各自的IO。进入地图后,会针对当前地图生成Controller,来实际从Player截获输入和部分输出操作,并真正影响到游戏中。相应的概念还包括View(实际上的摄像机)、ClientViewport(游戏和编辑器窗口)。
Controller-Pawn体系:Pawn是可以被Controller控制的东西,Controller把IO和UI消息转化为对Pawn的操作,通知Pawn完成其功能,并把这些功能执行过程反馈给IO和UI。在游戏中可以切换Controller内部的不同状态,例如根据Pawn是在走还是在爬墙,把输入消息转化为对Pawn不同的指令。还可以切换Controller,比如进载具了,Controller一换就Ok。甚至技能中也可以切换Controller,比较经典的例子就是虚幻竞技场3里的榴弹炮:普通架起来的状态下打出的是一般炮弹,炮弹飞行过程中鼠标可以一直控制其方向,右键可以把这个炮弹展开使其定位在空中,然后你的视角一直停留在这个炮弹上,鼠标变成在地面选择一个区域,火炮变成一门发射榴散弹的大杀器,把致命散弹砸向这个区域。笔者接触过不少游戏的游戏操作系统了——不幸的是这个流程很少有操作系统能够不加大改地实现。AI也是一种Controller,操纵的是Bot这个特殊的Pawn,这块儿有兴趣也可以研究一下。
World-Level-Actor体系:World里存一堆Level,Level里存一堆Actor, Build后的光照跟Level走,Level是关卡部分的资源单位。但场景图根是World里的Hash,虚幻3里是个八叉树实现。World里实现了基本的场景功能,角色的走跑、悬崖边缘的检测、走到碰撞体前被挡住、碰撞体位置变化时导致自己上面放置的其它碰撞体变化……你如果有自己的场景需求,可以修改World里面的这个部分。注意,在虚幻3里场景和物理虽然有关,但是本质上还是分离的,引擎提供了默认的整合方式,但你可以在Actor里重新控制这种整合。
资源体系:没什么好说的,Material、Texture、各种Mesh、Particle。Material连线球很赞,但是跟渲染Stage有较深的关联,笔者试图做过一个自以为比他更好的,跟Stage可以一定程度脱耦的材质连线球操作系统——但是最终发现材质这东西根本上还是离不开渲染Stage,什么都想控制的结局一定是什么都控制不过来。
渲染体系:就不说什么了吧,Deferred Lighting的Stage体系,网上的文章海了去了,做图形的这个早就抛脑后了吧。最近一两年的版本支持了Deferred Shading。这套Stage的低端化替换还是很方便的——毕竟现在需要考虑到游戏可能更多是会在intel HD 3000/4000这种显卡上跑的可能性了。
4、UnrealEd
编辑器……怎么说呢,这个没法按体系来了,太多了,有些精品也有些糟粕,反正编辑器这东西,没法说,需要扩展的时候自己去改吧。
注意属性编辑器是如何发挥反射的强大效力的。
有些细节问题,实际做了可能会遇到:拷贝对象时,有些属性是引用的(一般的Object属性不加任何描述),有些是复制的(editinlinenew、instance和duplicate),有些是舍弃的(transient)。还有就是虚幻比较喜欢用Prototype + Clone的方式来实现Template-Instance这种需求,典型的例子是Animation Tree和Prefab,实例都是直接从资源拷贝出来的。主要是因为UE3的反射外围有一个比较强大的Clone操作系统,但是前提是您得对刚刚列举的那些关键字比较熟悉,否则为这些操作系统扩展时就比较容易遇到问题。
多说一句:编辑器选物体用的是把物体的ID渲到一张Render Target上再去这个Render Target上查找鼠标点Id的做法,叫HitProxy,如果你的游戏想支持像素点选,可以参考这个东西,很容易就能把这个Stage集成到游戏Stage里。
5、其他工程
就没什么好说的了:
渲染器:Renderer,DX9、DX10、DX11、OpenGL的实现都有,DX10只有一个版本昙花一现。
平台库:以XXXDrv为名,例如WinDrv。主要提供平台方法,没什么好说的。
网络库:IpDrv、Channel什么的,也没什么好说的。
网游的开发者很喜欢自己构造上层,我参与的第一个UE项目就是这么做的,实际上最后做出来的上层后来看来比虚幻的整个上层体系差的太远。第二个项目笔者就一直推动着在虚幻框架上的小修小改。最后能实现什么呢?能实现在编辑器里根服务器通信,编辑器调整完Kismet连线图、资源、布怪点后,不用退出,直接就可以启动开发服务器,然后在编辑器内测试刚刚自己做的东西对不对,可惜因为资金原因没做下去,两年前这个级别的工具集成,不知道有多少人做到了?至少我现在在这个项目里还没能推广到,也不可能推广到那个程度(笔者鼻子翘起来了~*^_^*)。不过未来不需要再弄了——看看虚幻4的Blueprint,可以考虑这个级别的集成了。
笔者一直认为,虚幻3强大的地方不在于他的图形,而是在于这套强大而稳固的结构和迅速的工作流,而当你握这套结构和工作流后,笔者发现所有引擎在自己的面前索然无味,图形虽然还在追求,但已经退居次席了,而自己重新去做引擎的冲动则不断降低,直至完全消失。
用虚幻一定要首先明白一个原则,就是这是个解决方案式引擎,不是OGRE那样的图形工具库,所以你的所有改动一定要符合虚幻的基本结构假设,否则你只是在给自己找麻烦。但是,相信我,符合这些基本的结构假设一点不会让你的自由度降低,你的控制能力把控能力还是相当强的——不信你看,笔者上面列举的框架部分,有哪个是会影响你的发挥的?M——World-Actor、V——Player、C——Controller,哪一环是可以省略的?当然,如果您的体系结构设计的比这个还好,那真的很恭喜您了,一山更比一山高,笔者只能感叹于自己的时运不济了……
这两天还是在看例子,看几个Blueprint的例子,顺便回想一下UE3的那些事儿。最近的紧张局面可能会延续到4月中旬,届时才有可能有更多时间来看UE4。目前感觉变化还是挺大的,不过,喜在框架方面的改动似乎很有限。
从另一个方面,也证明了UE3的这套游戏上层逻辑框架,是多么地稳固和强大。
http://blog.csdn.net/noslopforever/article/details/24740961
前文说到UE3开始,虚幻就使用了UnrealBuildTool(以下简称UBT)来编译和生成代码。
为什么这么做而不是使用VS是很好理解的:因为VS跨平台会比较麻烦。像虚幻这样体量的工程,单为工程做一次VS配置就基本是一天的时间
而且UE4还不像UE3那样就十几个工程,把所有uproject都看做工程的话,得几十了。依赖关系复杂度几何增长,用VS的工具去维护……而且要维护各个平台和配置……再加上维护完后Mac、Linux还得维护一遍……
但是为什么不使用成熟的CMAKE呢,私以为可能是因为UBT里有一系列错综复杂的规则,用CMAKE制作出来,即便可读性OK,调试也比较麻烦。而且CMAKE对引擎使用者提出了一定的要求,而UBT则相对简单——只要你不纠结它如何实现。
官网的这篇文章详细解释了为什么要做一个Build Tool出来:
http://docs.unrealengine.com/latest/INT/Programming/UnrealBuildSystem/ProjectFileGenerator/index.html
What are the advantages of generating project files
可以先看看UBT的基本规则:
http://docs.unrealengine.com/latest/INT/Programming/UnrealBuildSystem/index.html
目前说来,虚幻的所有代码集中在下面几个文件夹里:
Root 的Source,这个文件夹里主要是引擎代码。
其中:
Source/Runtime里主要是引擎的核心代码。
Source/Developer里似乎主要是一些工具工程。
Source/Editor里是编辑器相关代码。
Source/Programs里是引擎使用中需要用到的工具。比如UBT、UnrealHeaderTool、Swarm(分布式光照计算操作系统)等等。
Source/ThirdParty里是各种第三方库。
Root 的Plugin,这个文件夹里有各式各样的Plugin实现。特殊的是Plugin的组织中需要多一个uplugin,可能是Plugin下可能会有一些资源什么的吧。我们后面再来看uplugin。
工程项目 的Source,如果是代码工程的话。
UBT目前只认这几个文件夹,也就是说,如果你要为引擎扩展功能,您只能在这些文件夹里创建自己的工程。这一点是在UBT里写死的,有代码的可以关注一下UBT工程的FindAllRulesSourceFiles这个方法。
在这些文件夹里,您可以搜索到大量的*.Build.cs文件,这些Build.cs就是虚幻的工程组织核心,基本上,每个Build文件都可以被视为一个工程文件,而Build文件所在的文件夹可以被视为此工程的根目录。接下来,我们不妨称这些拥有Build.cs的文件夹为工程。UBT一开始会先去找所有的Build.cs,把它们放在一起生成一个临时的dll。然后基于它们逐个进行一系列的代码分析工作,最后调用命令行进行编译和连接过程。
对于每个工程而言,代码一般都散落在下面几个文件夹:
Classes:如果你在工程根目录下写了个Classes,就相当于告诉UBT这些文件是要用UnrealHeaderTool来生成运行时反射信息的。所以,这个文件夹里头文件的写法必须符合可反射类的写法规范。
还记得虚幻的哪些类是可反射的吗?对了,所有UObject的派生类包括AActor的派生类。具体是否有所验证还没看,不过最好是按照这个节奏来。
规范上无非主要就是USTRUCT、UCLASS这些宏,抄几个就能找到感觉,或者用编辑器的类生成功能也可。
看起来,虚幻引擎发布时(不是通过编译生成,而是通过Launcher下载的那种),这些Classes文件是随引擎发布的,方便不具备全代码的Mod爱好者和BluePrint开发者们来制作游戏。
Public:公共头文件,跟Classes一样随着引擎发布而发布,所以这里一般都是些比较开放的接口,比如模块入口、功能核心接口什么的。基本上这些接口没有废话,很清晰,跟实现相关的细节隐藏得非常好。与Classes相同,如果你的工程里有Public,那么里面的.h就会被当作Public来。
Private:这个文件夹似乎不是虚幻定死的,也就是似乎可以不用Private的名字,或者多来几个文件夹什么的。除了UHT中有一段代码与之有一定关联之外,UBT里是完全没有跟这个有关的东西。它里面基本上就是各种实现代码,以及要在实现间共享的头文件。你也可以创建其他类似的文件夹,只需要Build.cs里写上相应的文件夹名即可:

此外还有需要注意的地方是Source根目录下的Target.cs文件,Target的最终目标一般都是可执行文件,可以说,Target是整个生成期的入口,生成会首先从找到Target开始,如果没有Target或者找不到,就会直接失败。
此外,需要注意的是,Target.cs里面写的类的类名,必须是Target.cs的文件名加Target,例如:Sample.Target.cs,其类名必须是SampleTarget。UBT的GetTargetTypeAndRulesInstance方法里印证了这一点。
UBT里面还是有不少限定用法的,Target就是其中之一,虚幻是一个比较强调命名的引擎,改名有很多麻烦,最好是能够一步到位。
今天抽空看了看文档,大概跟了跟UBT的流程,明天继续。

回复

使用道具 举报

0

主题

852

帖子

2829

积分

vip会员

Rank: 1

积分
2829
发表于 2015-10-12 23:45:34 | 显示全部楼层
嘻嘻   要是只看你的话      很容易让人家以为你也跟偶们一样是天使类  (偷笑中         
回复 支持 反对

使用道具 举报

0

主题

833

帖子

2784

积分

vip会员

Rank: 1

积分
2784
发表于 2015-10-13 02:14:45 | 显示全部楼层
也有啊 前天不是你也到一个很狂的贴里去了吗   
回复 支持 反对

使用道具 举报

0

主题

846

帖子

2784

积分

vip会员

Rank: 1

积分
2784
发表于 2015-10-13 02:55:00 | 显示全部楼层
好我骂你  
回复 支持 反对

使用道具 举报

0

主题

911

帖子

3028

积分

vip会员

Rank: 1

积分
3028
发表于 2015-10-13 06:48:54 | 显示全部楼层
不早了 各位晚安      
回复 支持 反对

使用道具 举报

0

主题

838

帖子

2730

积分

vip会员

Rank: 1

积分
2730
发表于 2015-10-13 16:40:03 | 显示全部楼层
楼主那种裂纸欲出的大手笔,竟使我忍不住一次次的翻开楼主的帖子……   
回复 支持 反对

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | enginedx注册

本版积分规则

 
 



邮件留言:


 
返回顶部