为什么unity愿意用c#作为代码语言,而虚幻却使用c++?
为什么unity愿意用c#作为代码语言,而虚幻却使用c++? 泻药,作为一个很喜欢这个引擎的UE黑头子,退乎前来理性分析一下,希望社区的哥们们轻点锤。同时我发现很多社区的朋友因为用多了U++,变得无法分辨引擎特性和语言特性了,这里权做一些指正。从结论来说,UE的这套东西成型非常早(C++04年代),并且经过了非常非常长期的迭代,所以从设计角度看现在处于一个尴尬的境地。比起隔壁联合的C#套装,比较落后。在现在的机器上,比起一些用lua的inhouse,性能优势也好不到哪里去。当然这里只是阐述当下的客观事实,并不是我对Unreal有什么轻视鄙视的想法。软件工程本就没有银弹,Unreal现在的体系,只能说是Epic在多年游戏制作中面向实际需求,完善内部工作流进行迭代的直接结果。
比起Unity这样的轮子专业户,Unreal面向需求(特别是内部需求)的味道非常强烈。那么对立地,设计层面上就必然显得不是那么优雅。
U++ & UnrealScript
虚幻只提供C++作为文本代码语言,只能说有历史遗留原因,也存在它自己的一些考量。
首先Unreal不用C#,并不是说它就不要脚本了。只不过比起使用现成的C#,lua等脚本,Unreal选择基于C++,造一套虚拟机,实现一套自己的脚本。这套东西,当年叫做UnrealScript,如今叫做BP,打底的就是大家所说的U++。至于为啥,首当其冲的自然是性能。UE的GC就是经典例子,C++实现的非通用GC,可以渗透到每个细小的角落进行优化(活用帧概念、考虑Streaming等),性能上基本算是无痛。
UE3的年代是Kismet和UScript并存的,并且有大量的代码遗留下来了。反射系统里面你可以看到UScript的各种痕迹,BP里面你也能看到各种Kismet的遗产。通用BP节点本身,基类也是以K2为代号的,取意自Kismet2。
那么这里就可以谈下我题首引出的那个问题了。作为脚本的底层,U++中的反射序列化网络GC等等一大堆特性到底属于语言特性还是引擎功能呢?结论是很显然的,它们是Unreal的引擎功能,同时是UnrealScript的语言特性。所以U++的各种东西都围绕着基类UObject来进行,而不是直接对C++进行语言机制补全。当UnrealScript被腰斩,这个RuntimeSystem透过C++直接暴露出来的时候,各种违和感就突显出来了。
用人话来说,C++拖着一个庞大的运行时系统,就是呈现在你面前的U++了。
被干掉的文本脚本
那为啥Unreal扔掉了UnrealScript呢?这可以算作Unreal面向内部需求采取的一种折中了。维护一套文本脚本比较费神是一点,但最大的原因在于Epic可能真的用不上这套东西。
作为主机平台的FPS专业户,Epic对文本脚本的需求可以说不是那么重。不像MMORPG,FPS游戏的大部分逻辑,都在场景里跑着的一个个Actor上。不像ARPG,有那么多复杂的技能。在实践中,策划甚至程序直接拉拉连连看,向场景里面一丢,就能实现大部分的功能。影响性能的,直接重构到C++。所以Epic发现自己真的用不了太多UnrealScript这团鸡肋了。
于是壮士断腕,奥利给干了,一刀下去UnrealScript就人间蒸发掉了。美国杨过,就这么横空出世了。
但是这刀下去,带来了一些灾难性的后果。爽了一时,爽不过一世。随着Unity步步紧逼,Unreal开源,Epic开始硬着头皮推进商业化社区化的大潮。各种各样的团队,多元化的需求,这时候开始涌现出来,独臂侠杨过这时终于发现耍不了双刀了。尤其是到了我们天朝更是水土不服,没了文本脚本,多人协作简直要了老命了。版本管理直接暴毙,复杂逻辑一直编译,种种蛋疼之处层出不穷。
BP好用吗?对我个人来说当然是好用的,对于做FPS的关卡设计来说那肯定是香的。但是痛就痛在为什么没有文本脚本呢?对于一些类型的游戏(MMO等)和超大型项目来说,这痛简直是痛到老二上了。
新时代的旧遗产
时光荏苒,在游戏之外,Unreal在视觉领域也披荆斩棘,打出了一片自己的天下。Unreal本身的功能已经强大到无与伦比,引擎的体量也膨胀到恐怖如斯的程度。
这时的Unreal想进行重构,已然是一件艰巨无比的任务了。迪拜塔都冲天上了,想动动地基何其容易啊。再说用户这么多,并且艺术领域的用户群体也大,完全重构的大版本换代,对用户和Epic自身而言都是很难接受的。Epic自然又选择了类似Win10的长期支持,滚动更新策略。
自此,格局就这么定下来了。作为吠舍群体,劳苦功高的程序员群体只能看着婆罗门美术们在Editor里面吃香的喝辣的,同时自己在VisualStudio里面吃翔的喝拉的。
让人不那么绝望的是,这个引擎还是在逐步变好的。很大一部分贡献来自社区支持,如果你想换掉蹩脚的UMG,有Noesis这样的GUI框架支持。如果你迫切的需要一套文本脚本,自有unlua等任君选择。
但有那么点不舒服的是,Unreal社区现在有股盲信盲从,满口官方工程师全能神,强无敌秒超平的不良风气,甚至很多人觉得官方就是最好的,从不关注甚至鄙视第三方组织的贡献。这与官方构建开源社区的理念也是背道而驰的,完全不利于社区的长期发展。
每个写过点编辑器和BP前端的少年们,都会怀想起当年自己在BP Graph里挥线如剑,纵横驰骋的英姿飒爽。每个奋战在RHI前线,彻夜撸管(线)的哥们们,又何尝不会于深夜忆起往昔,追念那Material Graph中的种种快意恩仇呢。 这个估计只能问当初开发unity那帮人了。
unity当初引入mono 和c#估计只是当成个脚本语言在用。 实际上最早的时候你是可以在运行的时候直接修改逻辑代码而不需要关掉运行模式的, 只要你按照特定的规则写。现在想这么干已经有点难了。虽然你依然可以在运行时修改代码和编译, 但难度增加很多,经常会丢引用什么的。实际上最早unity推荐的编程语言是javascript 或者现在大家都叫他unityscript… 后来才换成推荐语法比较严谨的c#。
mono虚拟机当初最大的好处就是跨平台, 2.x时代unity就经常被用来做3D 浏览器应用和3D页游。 3.x后可以几乎不用修改的部署到ios android 等各种平台。而其当时的游戏开发几乎都要单独为每个平台特制。
不过后来貌似unity打算抛弃mono ,毕竟运行效率还是有点低的。
UE 这边选择c++ 必然因为UE是一个很重型的引擎, 需要比较高的效率。 而灵活一方面是通过Blueprint 蓝图来提供的。 另外现在UE也可以通过插件来支持 C# 和 Lua 之类的。 谁跟你讲 C# 没有指针的……
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/unsafe-code-pointers/题主更新了问题,在此回答为何虚幻使用 C++。
其实可以反过来想,想用 C# 也好 C++ 也罢,市面上都有选择。
C# 和 C++ 用作游戏引擎还是各有取舍的。我并不在游戏业界,只能说一点浅薄的看法:
C# 的主要好处来自于内存安全,主要风险来自于 GC pause。而 C++ 的主要好处来自于极限执行效率,主要风险则来自于内存安全。所以其实问题的核心在内存安全上。不要小看内存安全的威胁,稍微搞不好可能就会导致项目难产的,很多项目组是承受不了这个风险的。 Unity本身引擎是用c++代码开发的,早期官方包装了三种脚本语言JavaScript、C#、Boo供开发者使用,降低使用者开发难度。其中c#使用开源mono,使用最广泛也最流行,也是Unity唯一幸存的脚本语言。又因c#的效率等诸多问题,再后来Unity推荐使用IL2CPP,转c#为c++提升效率。目前又推出Brust编译器(使用LLVM将.Net转化为机器码),使用Dots开发模式更进一步提升效率。Unity引擎c++层是黑盒模式,开发者是接触不到的,当然也可以花钱购买源码。黑盒也许保证开发更可控,避免滥用吧。Unity国内为了热更新方便,第三方开发者引入Xlua,Slua,toLua,ILRutime等框架,基本核心效率逻辑可以采用c++或c#写,lua脚本作为非效率业务逻辑开发。Unreal 核心引擎逻辑也是c++,早期官方也包装了UnrealScript供开发使用,来降低使用者开发难度。后来可能大量开发者觉得脚本层与引擎c++层面交互不够效率,脚本语言特性不够丰富等诸多原因,改为c++模式开发了,但c++开发门槛还是较高的,这可能是它得不到很好推广的一个原因吧,当然Unreal也自己可引入其他更好的脚本语言来做一部分业务逻辑开发。Unreal是开放了源代码,可以更自由的使用引擎层,但读懂也非常的难~~~~~
总结:Unity C#易用顺手,对初学者友好。Unreal c++上手难度大,需要很强的驾驭能力,没有中间层追求效果效率。 Unity早期支持很多种脚本语言,比如BOO、Unity Script(JavaScript for Unity)等等。但是新版本中不再推荐使用了,现在Unity的推荐开发语言为C#。
那么,为什么Unity选C#,而UE4不选C#?
1、Unreal Engine成熟的时间比C#还早
UE4是从UE3、UDK慢慢发展过来的,而UE3发布于2005年前后,发布时已经伴随成熟的游戏产品了。
算是成熟版本的C# 2.0发布于2005年11月,而C# 3.0直到2007年才正式发布。
客观上UE3、UE4不可能采用C#作为脚本语言。
那个时代流行这种LOGO风格,现在都是黑白灰扁平化
2、Unity支持C#是多方面考虑的结果
Unity 3.0的发布时间大约在2010年前后,在Unity早期立项时,选择C#的客观条件已经成熟。
可喜的是Unity没有选错语言,而且抱着微软大腿少走了很多弯路。开发者们也非常喜欢C#语言,用过的都说真香 :)。
Unity早期打算支持多种编程语言,包括不限于C#、Boo、UnityScript等等。这说明一件事——Unity当时打算通过降低编程门槛的方式吸引大量游戏爱好者和初级开发者。用现在流行的话来说就是战未来。
事实证明,Unity的一系列商业策略确实成功了,常听到的说法是Unity对UE在商业和技术上实现了弯道超车。
3、大幅度改变脚本架构成本很高
像UE、Unity这种体量的成熟引擎,它们的编程体系已经经过了无数次优化和测试,达到了比较好的水平。强行在现有情况下加入对新脚本语言的支持其实是非常困难的。
为什么这么说呢?因为:如果新加入的语言不成熟,就不会有人去用;而如果没有人用,新系统就不会成熟。这是个负反馈叠加的状态。
除非市场环境有巨大变化,Unity和UE都不会大幅度改变现有的编程方式。
从2020年的时间点看,由于现在正处于一个“游戏多元化”的历史阶段。手机游戏、PC游戏、家用机游戏、HTML5游戏等等,都有各自的市场。每个市场特性不同,从而每个市场都有更青睐的引擎。
综合来看,不同的引擎有它最适合的语言。目前UE4采用蓝图和C++,Unity采用C#(某些项目会加上一点Lua),算是达到了一个均衡的状态。 c#作为胶水语言,是相对比较平衡的。
往表层有dynamic,await,简单逻辑可以保持简单。
需要基元操作时也比较齐全,各种位操作,无符号数,强转,Layout控制,Union,指针,栈分配数组,值类型,引用。
特别性能敏感的地方,引擎本身还没有提供的话(引擎本身主要是c++写的),还可以调DLL或者SO,关键代码你写汇编都行。
其实一般情况,就C#里用点SIMD,养成只在必要的地方堆分配,性能是很好的。
Unity有IL2Cpp后端,除了牺牲动态反射外,基本上可以同时享受中层语言的省心个偏底层语言的性能。对于大多数以创意和风格取胜的小工作室来说是非常对口的。
工具没有最好,只有最适用。用好了都能创造价值。 虚幻希望开发者尽可能能用蓝图来编写游戏逻辑吧,引擎本身C++效率比较高,Unity引擎也是C++的。另外Unity可以用C++,虚幻也可以用Lua或者python。 unity啥时候用python作为脚本语言了?另外虚幻有C++??那个不是叫U++么(滑稽)
好吧说到底就是C#容易入门,写起来舒服,比较符合Unity的引擎理念这样子吧 py的性能就不多提了,是多扔一点算法就没优化空间的东西,u3d当时是boo 和py有点像而已,还有http://js.net,假js,以及c#,unity当时看上mono时也是想找个方便点的能当脚本性能有还行能跨平台的东西,而java jvm又不是你能乱动的,用c#可以让人少写cpp,确实unity做点普通游戏完全可以不用cpp,只不过当时u3d的mono才对应.net2.0,也没有对这套东西特别重视。
即便如此,c#的强类型,性能,丰富的类库,确实是一个便利的选择,mono: 送你套类库要不要,以u3d的定位来说是很好的东西了。随着版本的迭代,发现c#真越来越好用了,经过mono .net4.x .net standard的混乱后,.net5终于准备一统江湖了,之后就更舒服了。
ce也使用了c#语言,他看到了u3d用c#用的挺爽的,他也要用,免费获得一套生态丰富的平台。
而ue是最傲气的,他自己搞的uscript虽然放弃了,但是他也不愿意投入c#怀抱,凭什么别人用我就要用,ue可是有自己的脚本引擎团队的,需要脚本也不会用你c#,根本不care,说到底老子的u++才是王道,该你们搞c#转来搞u++
民间一直有c#适配ue的开源项目,但是ue一直处于漠视态度。
说到底还是ue的历史积累深,不需要c#的生态来帮忙,自己能搞定。
还有,蓝图这种图形化写逻辑也不是啥高端新鲜货,工控界这么不喜欢写代码的领域,早就有labview这个东西了,接近人思维逻辑的东西用流程图好用,更接近机器思维和算法的东西,太费劲儿了,就这么个特点鲜明的东西,拉到工控领域,是不是瞬间就觉得也就那么回事儿了。话说工控的界面逻辑和游戏还真有那么点像。