原文作者:Maik Klein
原文地址:https://maikklein.github.io/2015/07/20/Unreal-vs-Unity/
调试
调试对于我来说非常重要,我们可以通过调试知道应用程序的运行过程。
在UE4中,你可以按F5,在编辑器中启动调试模式,在这个过程中,你可以随时修改代码,但是不能在Vs中进行编译。幸运的是是,你可以在编辑器中设置断点,进行编译。
调试功能甚至可以使用在网络游戏中,这一点非常棒。我们可以想象以下情形,4台客户端1泰服务器,然后你在一个被所有客户端调用的函数上设置断点。断点将触发4次,在任何时候你都可以检查你喜欢的值
Unity也可以调试游戏的代码,但他并不像UE4那样流畅,它有一个插件叫UnityVS,这个插件可以加载于编辑器或某一程序中,不幸的是,在我的机器上调试很慢,如果我加载UnityVS到编辑器到播放模式需要10秒钟时间。
而且Unity的调试只能调试一个实例,如果你正在创建一个网络游戏调试实例,这将很烦人,UnityVS不允许编辑正在调试的代码。。
稳定性
我认为Unity和UE4都有一些不稳定。
这是非常奇怪的一点,我觉得Unity和UE4都是不稳定的。我花了仅仅两天的时间,我的Unity项目变的糟糕并且很难修正,经过不少时间,我找到了原因,因为我写了一个自定义工具放在Standalone游戏的asset文件夹中,这导致了一些非常奇怪的错误发生,有些时候,我正在编辑器中编写脚本,Unity同样崩溃了。
UE的编辑器经常会崩溃,有时会检测不到Blueprint的变化。对于C++也会存在相同的情况。但是至少可以直观的找到到底是哪里出了问题。比如,编辑器的的编译按钮消失不见。
操作不当的时候UE4也会经常崩溃。比如,忘了做空指针检查然后访问了空指针。所以需要经常进入调试模式,否则会得到很奇怪的提示。
但在Unity中代码还没有崩溃过。在Unity中你访问了空指针,它会记录下来。
项目升级
项目升级对于UE4来说是短板,每次Epic发布小版本升级,都会出现各种出乎意外的问题。
我的建议是等待并且使用与最新版本至少相差一个的版本。如:最新版本是4.9,你可以从4.7升级到4.8版本。因为,至少这个时候,一些常见的问题会发现出来。建议不要升级到最新的版本,除非最新的版本有一些特有功能。
我并没有在Unity中升级过项目。但是我推测一些问题仅会发生在主要版本的升级上。
开源
开源对于我来说是非常重要的,遇见问题自己可以解决。并且对于了解API的工作原理也很有帮助,坦白说,Visual Studio中的百万级的C++代码量实在是太大了。但是有游戏框架的源码已经非常好了,我现在经常研究。
与UE4不同的是,Unity是闭源的。
举个例子:Unity最近发布了UNET,适用于Unity的多人解决方案。附带了类似于NetworkManagerHUD原形脚本一样的脚本,提供了一个简单的GUI。你可以启动服务器,或者作为客户端连接到服务器,但是如此简单的脚本实现都是不可见的。
编码
UE4使用自定义的C++方案,编写C++时主要使用很多宏指令,这些宏指令会生成的一些代码提供给UE4的Header Tool,它会生成一些代码。
UE4有些陷阱需要注意。例如,如下代码:
UFooComponent* FooComponent; .... FooComponent = CreateDefaultSubComponent(TEXT(“Foo"));
这个指针将会被重置为null。需要像这样注释宏指针。
UPROPERTY() UFooComponent* FooComponent;
Unity使用自定义的C#解决方案,我了解到他们正在使用IL充血UNET,并且我确信他们对对MonoBehaviors做了同样的事情,因为我找不到Start的方法。
在Unity中可以写成这样:
[SyncVar] float health;
它会将值从服务器同步到客户端。
在UE4中写法如下:
UPROPERTY(Replicated,Reliable) float Health; ... DOREPLIFETIME(AFooSomething, Health);
悲催的是,Unity仍停留在.Net3.5,不久以后可能会被IL2CPP所替代,但目前仍旧是使用.Net3.5。
Unity的游戏框架很底层。你有绝对的自由去做任何你想做的。
UE4强制你使用它的游戏框架,它可以适应很多游戏流派。但限制了架构上的自由。UE4游戏框架使用了大量继承,这很死板。
好处是你可以从头开始随意创建自己的素材。
在Unity中你必须使用GameObject,然后才可以为其加上MonoBehaviours。
UE4有类似的东西叫做Actors和ActorComponents。主要是可以使用Actor的子类。
比如,可以创建:
class AMonster: public AActor
然后在运行时,检查一些角色是不是怪物:
AMonster* Monster = Cast<AMonster>(SomeActor);
在Unity中你可能这样创建怪物组建件:
public class Monster: MonoBehevaior Monster monster = gameObject.GetComponent<Monster>();
还有一种选择,使用标签:
gameObject.tag = “Monster";
但是我非常不喜欢这样使用字符串。
示例
Unity和UE4都有很多学习资料,但是大多数都是关于如何使用引擎的。基本上没有高级的编码示例。
Epic Games举办的Unreal Tournament(Unreal开发大赛)是UE4的一大亮点。可以从中学习Epic内部是如何使用UE4的。
网络
UE4的网络工作流是非常棒的。只需要点击play,编辑器会自动生成多个游戏实例并连接它们。
Unity并没有用于多人游戏的工作流。于我而言,C#的主要优势是它的编译速度。但是在Unity中,如果你想要多个游戏实例的话,需要单独编译出一个游戏,编译创建那些二进制文件需要花一些时间。
这就是我自己写了一个超级编辑器脚本的原因,它能产生4个游戏实例,将他们绑定到我的第二个监听器,启动编辑器作为服务器,并连接4个客户端。
你可以在这里找到这个脚本:https://github.com/MaikKlein/UNetHelpers
总之,UE4的网络和Unity的UNet感觉很像,但是UNet带有附加功能。Unity有一个中转服务,NAT穿透,一个大厅系统,使用它创建主服务器很简单。Unity也可以收取少量费用,在AWS云上帮你托管游戏。这个服务对一小部分用户甚至是免费的,对于像我一样的独立开发者来说很诱人。
我可以托管我的demo游戏和朋友一起玩。在UE4中,没有NAT穿透,所以需要开放一些端口。但是至少在UE4中你可以创建专属服务器。
在Unity中可以在不同的频道发送消息。比如,你可以在频道0发送位置更新消息,重要一点的消息在频道1发送。也可以在特定频道设定消息协议。比如,你可以将频道0设置为不可靠的,将频道1设成可靠的。
相比之下UE4使用单独的属性来标志是否可靠,并为创建的所有角色创建一个频道,然后使用FObjectReplicator来复制属性。
你可以使用 GetNetPriority来控制角色的优先级。
定价
UE4没有任何附加条件,但是会从你的收益中获取分成。
Unity有两个不同的版本,个人版和专业版。个人版基本上没有附加条件,但是你一年的收益要低于10万美元,且不能自定义启动画面,也没有黑色的编辑器界面。专业版包含一系列服务。
我发现在Unity个人版中不能定制启动画面很烦人。我其实并不关心我的用户是否能看到Unity的启动画面,我关心的是使用Unity UNet开发我不得不创建一个单独的游戏。这意味着每次要测试一些东西都必须观看启动画面。
我觉得Unity应该允许在开发项目时禁用启动画面。
社区
Unity的论坛可能比UE4数量更多。Unity在Reddit的话题数量比UE4多2.7倍。当你遇见一些常见的问题的时候,从社区获得解答,是一个非常有利的事情。