其他分享
首页 > 其他分享> > 乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - .NET和Unity的未来(来自Unity官方告白)

乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - .NET和Unity的未来(来自Unity官方告白)

作者:互联网

image

我们最近发起了一次持续数年的改进行动,帮助用户更快地编写性能更高的代码,并带来长期的稳定性与兼容性。请在本文中了解我们在更新脚本基础技术栈方面所做的努力。

.NET生态正在多方面上积极动态地演变,而我们希望尽快将这些改进带给广大用户。我们内部的.NET技术小组正致力于不断改进.NET集成,更新最新的C#特性与.NET Standard 2.1。但根据大家的反馈,我们最近又在全面改善开发者体验上投入了更多力量。

本文将介绍我们正在努力解决的几个问题。相关话题已在GDC 2022的Unity Dev Summit上被讨论过。你可以在这里回顾完整演讲。

.NET和Unity的演变

Unity与.NET的故事要从17年前说起,当时我们的CTO决定开始采用Mono .NET运行时和C#。Unity之所以偏爱C#,不仅是因为它很简单,还因为JIT(just-in-time)编译器可以将C#代码转译成效率较高的原生代码。而为了做到性能平衡、可控,Unity引擎剩下的大部分都采用了C++开发

IL2CPP(Intermediate Language To C++) 是一种由Unity开发的脚本后端,可在为各种平台构建项目时替代Mono。使用IL2CPP构建项目时,Unity会在为所选平台创建本机二进制文件(例如.exe、apk、.xap)之前将脚本和程序集内的IL代码转换为C++。IL2CPP的一些用途包括提高Unity项目的性能、安全性和平台兼容性。

多年来,Unity一直依靠着Mono .NET运行时和C#语言(2.0)的一个特定分支来运行。在这期间,引擎对其他平台的支持也在不断扩增。我们还开发了自己的编译器和运行时:IL2CPP让你能够针对iOS及部分主机平台进行开发

与此同时,整个微软.NET生态系统也在不断发展,并推出了新的许可和对非Windows平台的支持。我们借着这股东风在2018年升级到了Unity .NET Mono Runtime,并引入了更现代的C#版本(7.0以上)。同年,我们还发布了Burst编译器的首个版本,开创了为C#分支快速生成原生代码的先河。在取得这一突破后,Unity提出了一个新设想:将C#拓展到引擎剩余几个关键部分、不再用C++进行开发,并为DOTS运行时的开发做铺垫

Unity 2020 LTS和Unity 2021 LTS带来了新版C#语言和.NET API(如Span)。同时,我们也看到.NET生态的性能有了极大的改善,其引入的csproj SDK风格和蓬勃发展的NuGet生态正在让开发环境变得更加友好

我们将要做的事

经过长时间的发展,Unity已经包含了一个巨大的C++代码库,它继承了Mono .NET Runtime的职能来直接与.NET对象互动。这些代码对.NET (Core) Runtime来说不再合规或高效。

此外,Unity编辑器还绑定着一条复杂的自定义编译管线,它不依靠MSBuild运行,因此也不能轻易从引擎特性中获益。

在过去几年里,我们也一直在积极与广大用户交流,包括个人采访和Unity论坛,以发掘出真正能促使用户成功的改进。我们听到大家非常想使用最新的C#语言、.NET运行时技术和NuGet的第三方C#代码。在谈到Unity平台的使用时,大家都说希望借助高质量的C#测试、调试和剖析工具,标准.NET API和Unity API的优秀整合,来最大限度地挖掘出硬件的性能。 作为一名Unity C#程序员,你希望Unity工具能够与工具箱中的其他工具无缝衔接,能实现快速迭代,从而实现一流的运行时性能。

要达到这个目标,我们得花几年时间。我们将频繁更新博客和论坛,让大家了解我们在前进道路上遇到的技术挑战。

我们的做法

这项计划的第一步是在Unity内部集结所有热衷于C#和.NET的内部员工,建立一支C#/.NET技术小组来开展工作

我们的工作将建立在.NET生态系统之上,而非开发定制解决方案。为了让用户能享受新版.NET SDK/Runtime和MSBuild所带来的性能与生产力提高,我们将从Mono .NET Runtime转移到CoreCLR,即现代的.NET (Core) Runtime

这项行动也会带来当前.NET领域以外的创新,让C#脚本能更快地完成.NET迭代。我们将致力于结合IL2CPP和Burst这两个JIT和AOT (ahead-of-time) 解决方案,在编译效率和CodeGen(代码生成)质量之间的达到最佳平衡。

在外部,我们将与微软、JetBrains等业内伙伴合作,保证Unity创作者能用上最新的.NET技术。我们也在进一步深入参与开源社区。 这项工作将分成几个步骤进行。再来看看我们未来的计划。

2022年的工作内容

今年,我们的团队计划在以下几个方面开展工作。

image

C#开发流程

迭代时间仍然是我们首要的工作重点,我们清楚每一名用户都想尽可能地利用起自己的时间。以下是我们改进工作的几个例子。

至于转移到MSBuild,我们第一步须将编译管线与Unity编辑器分割开来,并将其转移到一个单独的进程中。这个过程涉及多年以来遗留下来的成千上万行C++和C#代码,我们要实现这一目标就必须解开这些代码——同时还要保持向下兼容。这项工作并不会在用户的角度带来多大变化,但它将铺好通往MSBuild的道路并简化引擎的维护

我们还将改进Burst的C# IDE调试体验,推出一种新的调试模式,当用户在Burst代码路径上设置断点时,自动将调试器切换到托管调试。这意味着你不必再手动删去调试路径上的[BurstCompile]属性。

现代化.NET运行时

转移至.NET CoreCLR运行时的工作已经开始,这是一个非常具有挑战性的旅程。为了使整个过程能够顺利完成,我们将分步骤解决各个问题,并在保证现有Unity项目稳定的前提下碎片化发布更新。

因此,整个迁移过程将分多个阶段完成:

现代化Unity运行时

Unity 2021 LTS新支持的.NET Standard 2.1使我们能够从多个方面着手现代化Unity运行时。我们目前正在推进两项改进工作。

改进async/await编程模型。基础性的async/await编程方法主要用于编写必须异步完成、不阻塞引擎主循环的游戏代码

2011年,在async/await成为.NET的主流之前,Unity引入了基于迭代器的异步运算协程(coroutines),但这种方法并不兼容async/await,并且效率也更低。同时,.NET Standard 2.1一直在改进C#和.NET对async/await的支持,推出了ValueTask来更高效地完成async/await的运算,并允许用户自行用AsyncMethodBuilder编写的类任务系统。

在有了这些改进之后,我们将努力结合async/await与Unity中现有的异步操作(如等待下一帧或等待UnityWebRequest的完成)。第一步,我们将引入取消令牌(cancellation token),改进MonoBehavior被销毁时或退出运行模式时被挂起异步任务的取消操作。我们也一直在与UniTask作者等社区贡献者密切合作,保证他们能够用上这些新功能。

利用Span减少内存分配和拷贝。Unity本身是一个带有C#编程外壳的C++引擎,两种语言之间存在着大量的数据交换。这就造成引擎经常性地来回复制数据、分配托管对象,造成工作效率低下。

C# 7.2引入的Span可以有效改善这个问题,且.NET Standard 2.1默认可使用Span值类型。近年来,你可能听说过或读到过许多归功于Span的.NET运行时重大性能改进(改进细节可在.NET Core 2.1、.NET Core 3.0、.NET 6、.NET 6等博文中了解)。我们同样希望在Unity中利用起它,并有效地减少分配,从而减少Garbage Collection卡顿、提高大量API的整体性能

加入我们的旅程

相信大家和我们一样对这些变化和功能感到非常兴奋。

https://unity.com/roadmap/unity-platform/engineering

欢迎大家来论坛留下自己的想法。我们将定期更新Unity路线图的引擎工程部分,你可以在那里与我们分享你的功能需求和优先事项建议。

参考

标签:C#,代码,Unity,我们,跨平台,NET,Net,运行
来源: https://www.cnblogs.com/taylorshi/p/16614677.html