第一,我们首先需要知道Unity与C#的关系是什么?
第二,我们要明白为什么Unity会使用C#,而不是C++?
第三,我们需要知道Unity是怎么使用C#的?
第一点:
先说结论:C#是Unity用于开发游戏的主要编程语言之一,而Unity则提供了一个集成开发环境,允许开发者使用C#来编写游戏逻辑。
再说过程:首先我们想要知道Unity和C#关系是什么?我们就需要知道什么是Unity、什么是C#,也就是要明白这两者的概念。
那么什么是Unity呢?
简单来说,Unity 就是一个 2D/3D 引擎和框架,为您提供设计 2D、2.5D 和 3D 游戏或应用场景的系统。
什么是C#呢?这里我们引用百度百科的原文:
C#是微软公司发布的一种由C和C++衍生出来的面向对象的编程语言、运行于.NET Framework和.NET Core(完全开源,跨平台)之上的高级程序设计语言。
但是Unity的底层是用C++编写的,提供了核心功能,如图形渲染、音频处理、物理模拟等。然而,Unity为开发者提供了一个使用C#作为主要编程语言的高层脚本环境。
那么,为什么Unity会选择C#呢?
第二点:
要明白为什么Unity使用C#,就不得不谈到C#的一些特性了。
1.我们知道C#是专门为.Net设计的开发语言,C#设计之初就考虑了跨平台的需求,这与Unity引擎的跨平台目标相契合。C#能够在不同的操作系统上运行,而不需要针对每个平台编写特定的代码。具体关于C#是怎么实现跨平台的可以看我的关于.Net的这篇笔记
C#高级编程笔记--.Net体系结构_c#界面高级编程-CSDN博客https://blog.csdn.net/qq_62520130/article/details/136529829?spm=1001.2014.3001.55012.与C++相比,C#的内存管理和异常处理更加自动化,减少了开发者的负担,C#提供了垃圾回收机制,这有助于管理内存并减少内存泄漏的风险,这对于游戏开发中的实时性能至关重要。
在下面我引入一段Unity官方的回答:
Unity之所以偏爱C#,不仅是因为它很简单,还因为JIT(just-in-time)编译器可以将C#代码转译成效率较高的原生代码。而为了做到性能平衡、可控,Unity引擎剩下的大部分都采用了C++开发。
与此同时,整个微软.NET生态系统也在不断发展,并推出了新的许可和对非Windows平台的支持。我们借着这股东风在2018年升级到了Unity .NET Mono Runtime,并引入了更现代的C#版本(7.0以上)。同年,我们还发布了Burst编译器的首个版本,开创了为C#分支快速生成原生代码的先河。在取得这一突破后,Unity提出了一个新设想:将C#拓展到引擎剩余几个关键部分、不再用C++进行开发,并为DOTS运行时的开发做铺垫。
回答链接:.NET和Unity的未来 - 技术专栏 - Unity官方开发者社区
总的来说,就是因为C#的简单高效跨平台和越来越完善的.Net生态系统。
关于C#与.Net的关系可以看我上面的笔记,里面记载的十分详细,一定会对你有所帮助。
那么,Unity内部是怎么处理C#的呢?
第三点:
Unity内部处理C#的流程如下:
1.脚本编写
开发者使用C#编写游戏逻辑,并将其保存为.cs
文件。
2.脚本编译
在早期版本的Unity中,C#脚本通过Mono虚拟机进行编译和运行。Mono是一个开源的C#和CLI(公共语言运行时)实现。从Unity 5.6开始,Unity提供了IL2CPP这一编译选项,它将C#代码转换为C++代码。这样可以提高性能,并允许C#脚本在没有Mono运行时的平台上运行。
如果是使用Mono作为运行时,C#脚本会被编译成中间语言(IL)代码,然后由Mono的即时编译器(JIT)在运行时转换为本地代码。如果项目使用了IL2CPP,则在构建游戏时这些IL代码将被转换成C++代码。
3.API绑定
编译后的C#代码需要与Unity引擎的C++底层进行交互。这就需要API绑定,它允许C#脚本调用由C++实现的Unity引擎功能。Unity通过一个称为C# wrapper的机制来实现C#和C++之间的绑定。这个wrapper层提供了一组C#可以访问的API,这些API在背后调用了C++的实现。
API绑定通常涉及到对C++代码的封装,以提供一个C#友好的接口。例如,一个C++类可能被封装为一个C#类,使得C#代码可以像调用本地对象一样调用它。
4.构建游戏
在准备将游戏部署到目标平台之前,Unity会执行构建过程。如果使用IL2CPP,则在构建时C#代码会被转换成C++代码,然后编译成目标平台的机器代码。