Unity —— 从UE4到Unity的转变和思考

来源:互联网 发布:上海知恩服饰怎么样 编辑:程序博客网 时间:2024/05/18 22:55

这篇博客记录了我接触并使用Unity后,就使用过程中遇到的一些问题所产生的思考和想法


背景

到动笔的日子(2017/04/19),也刚好跳槽满半个月了。新公司的项目所使用的游戏引擎是Unity —— 这也就意味着我需要抛弃使用两年半的UE4,进而投入Unity的怀抱。经历了磕磕绊绊的探索之后,我个人认为自己对Unity已经基本上手,这篇博客也就用来记录一下一个Unity初心者产生的想法吧……

开发流程的转变

开发流程的转变对我的工作内容影响不能算大 —— 以前相对来讲团队更小的时候,作为主程我必须要时时关心整体的开发流程,而现在我需要的是沉淀,因此开发流程对我的影响并不太大。但我还是想聊一聊这一块的东西:

UE4的开发流程(自认为合理的开发流程)

就UE4来讲,由于Blueprint的横空出世,因此开发业务逻辑的难度空前降低,低到只要有正常人的智商都能够快速实现各种基本的业务逻辑开发。

但是由于Blueprint一来速度较慢(官方曾经承认至少慢10倍,不知道这个数值现在是否有优化……),二来不好维护,三来Debug操作极为繁琐,因此Blueprint更加适合于设计的验证、原型Demo的开发。当设计想法验证完成后,往往由程序来进行功能的拆解和重构,将其转化为C++代码(有些团队会使用Lua绑定,也是很赞的方向……),也方便日后进行优化。

因此我个人认为比较合理的团队开发流程如下:

Created with Raphaël 2.1.0UE4的团队合作开发流程老板老板策划策划程序程序要加一个新功能,blahblah...用蓝图很快做一个粗糙但是能说明问题的Demo提供一些技术支持您看看要的是不是这个?不是,我要的是blahblah!!!用蓝图再次很快做一个粗糙但是能说明问题的Demo您看看要的是不是这个?提供一些技术支持差不多是这个意思,可以细化和美化了要加一个新的功能,是blahblahblah...将需求分解为轮子,进行基础开发将轮子分解为可供蓝图调用的节点交货

上图是我个人认为的一个UE4下比较健康的工作流程(极简版),这种工作流程能够让整个团队进行快速的需求迭代及确认。要知道程序最讨厌的就是不明确的开发需求,需求不确定则很容易导致无效的开发,任务也不好细化。

Unity的开发流程应该算是比较传统的吧(应该……)?因此这个差别是我目前体会比较深的……

语言的转变 —— 从C++到C#

就游戏逻辑的开发语言来说,虚幻的语言是C++,而Unity使用的则是c#。相比来讲我个人对于C++更加熟练 —— 但是从C++转到C#似乎也几乎没有花费我什么时间。

不适应的地方当然会有,老生常谈的话题诸如一个是即可面向对象又可面向过程的语言而另一个则是纯面向对象就不提了,这些东西往往注意一下语法,调整一下开发思维,再参考一下已有的代码,那么就基本上就解决的差不多了。

有些地方是花了我一些时间去适应的,例如模板 —— 模板由于纯面向对象的原因,导致在C#中无法进行随心所欲的模板编程了。当然也有可能是我对于C#的理解还不够深,说不定日后我会打自己的脸……

另外就是C#中不再有宏了,这一点让我倍觉可惜。需要再三说明一下我是个实用主义者,也就是说从不走极端——任何东西只要对我有用我都会认为其有价值,宏也一样。可能在很多人的心中宏这个东西简直就是糟粕,但是有些时候宏却很有用……UE中的很多代码也使用了宏的黑科技,也并未对项目造成太大的影响。

材质&Shader开发的转变

UE4的Graphics Development主要是在Material Editor上,在这里引擎有提供很多现成的节点可供开发,也提供了很多现成的着色模型(基于KK的毛发,基于次表面散射的皮肤等……)。这对于美术来说是个福音 —— 只要你所需要的效果与市面上主流的效果差别不要太大,那么70%的工作都可以使用材质编辑器来快速完成,剩下的30%中的70%又可以使用UE4的Custom Node+hlsl代码完成。

但是,由于UE4针对于这些功能进行了高度的封装,因此当你想要一些独有的,比较少见的效果时,就需要花费很大的功夫来进行引擎的定制化了……而引擎的定制化又往往会伴随着代码管理的工作量,因此这是一个鱼与熊掌不可兼得的情况。

Unity就单纯的多,使用纯粹的cg/hlsl代码来进行开发(ShaderForge似乎也为Unity的Shader开发提供了很大的助力),因此总体来说……有好有坏吧……

骨骼/Rigging/动画开发的转变

Unity在骨骼/Rigging/动画这一块带给我不少的思考。我花了好一段时间才渐渐适应Unity在这一块的开发思路。

与UE4不同,Unity使用的是CPU蒙皮,而且Unity的骨骼可以是场景中的任何一个Transform!

可能Unity开发者体会不到我的惊讶,居然还可以使用这种方法来实现骨骼/Rigging/动画系统!

在UE4中,这个系统是以Skeleton/SkeletonMesh/Anim_BP&Animation为基础实现的。任意一个在场景中的骨骼模型都有一个独立的Skeleton,通过骨骼的运动,驱动对应的顶点到达对应的位置。

这种做法的好处是效率较高 —— 引擎直接驱动骨骼,骨骼通过蒙皮信息驱动顶点直接到达期望的位置。坏处则是不如Unity灵活……

与之相对的是Unity在这一块的奇葩 —— 开发者可以在SkinnedMeshRenderer里面的sharedMesh中找到一个BindPoses的数组,这个数组储存了各个骨骼的绑定信息,具体的值为Bone[i].transform.WorldToLocalMatrix * sharedMeshRenderer.transform.LocalToWorldMatrix。

这也就是我说的所谓“奇葩”的原因 —— 由于Unity的顶点是储存于sharedMesh中的,因此如果想要计算出正确的骨骼驱动的位置,则需要先将Mesh中的顶点变换到世界坐标系中,再将世界坐标下的顶点位置变换到骨骼的本地坐标系中,最后再通过蒙皮信息来进行最终位置的确定……

坑爹呢这是!!!

开发思想的转变 —— 基于继承到基于组件的转变

开发思想……这是一个很大很泛的词,而且可能凭我目前的资历也没有资格提这个词……但是我还是想要提一提。

在UE4中,开发思想主要是基于继承的。虽然UE4也有组件系统并且在整个游戏逻辑中占了很大的比例,但针对于游戏的特殊需求,还是基于继承的开发模式更加通用。

UE4提供了很多的基类,并且又由于开源,因此很多时候开发者要做的就是基于这些基类进行继承开发,通过继承开发来达到自己的特殊需求。

而Unity则更倚重基于组件的开发,场景中的各种GameObject可以随便挂各种Component,再通过自定义Component(自定义Component与核心Component的交互)来达成自己的需求。

这一点给我也带来了一些不适应 —— 一开始还想自己创立一个新的SkinnedMeshRenderer,然后进行自定义需求的开发……失败!!!

不过也可以理解……Unity不开源,看不到实现的细节也的确很难进行继承开发……

开源万岁!!!

结语

从UE到Unity的确是一个不小的转变,两个游戏引擎的功能、倾向和架构都有自己的特点。还有很多的东西给了我很多思考,以后有机会再写吧……

<全文完>

0 0