Unity跨平台原理

在我刚开始用Unity的时候,只是想做Windows和IOS的小游戏,但是当我选择要发布时,看到Unity能发布的各种平台感到非常惊奇。那么Unity是如何实现跨平台的呢?

一个引擎为了实现效果有多个组成部分,因此我觉得要从不同的方面来讲。

1.图形系统

2.物理系统

3.光照系统

4.网络系统

5.脚本系统

 

图形系统

我们知道最经典的API有OpenGL和DirectX,除此之外还有为移动设备而生的OpenGL ES,针对浏览器的WebGL,以及Apple新推出的Meta等等l。

Unity通过将各种图形API集成到自身来支持各种平台。

 

物理系统

Unity通过Nvidia的Physx来实现物理效果。Physx是Nvidia设计的一套能够执行复杂的物理计算的技术,支持各种平台。

 

光照系统

在5.0以下版本,Unity是采用Autodesk的Beast来实现光照的。5.0以后,Unity与Geomerics建立了合作关系。采用了Enlighten技术,从而实现PC、主机和移动游戏中的实时全局光照。

 

网络系统

之前Unity的网络系统UNET不怎么出名,反倒是Photon用的人很多,我也用过,操作较为简单。现在UNET也不错,都能支持多平台。

 

脚本系统

跨平台中最核心的地方就在于脚本系统。Unity支持两种脚本,Unity Script和C#,那它是如何做到让这两种脚本编写的游戏导出到各种平台的呢?

核心在于MONO与IL2CPP。

 

MONO

首先介绍下MONO是什么。Mono是一个由Xamarin公司所赞助的开源项目。它基于通用语言架构(Common Language Infrastructure ,缩写为CLI)和C#的ECMA 标准(Ecma-335、Ecam-334),是微软.Net框架的另一种实现。但是与微软的.Net框架不同,Mono具备了跨平台的能力,它不仅能运行在Windows系统上,还可以运行在Mac OSX、Linux等平台上。

需要注意的是在iOS平台中Mono无法使用JIT模式,而是以Full AOT模式运行的。意思是面向iOS的C#代码会通过AOT编译技术直接编译为ARM汇编代码。原因是Apple封闭了内存的可执行权限。

介绍完MONO,现在就可以说明Unity跨平台的原理了。Unity在打包项目时,把MONO打包进去了,并且剔除了框架中不用的类。MONO运行实际上是运行在MONO VM上的,也就是说,Unity通过将代码转换为IL再在MONO VM上运行原生代码

mono

IL2CPP

2014年中期Unity建立了IL2CPP的概念,意在取代MONO。IL2CPP首先用于IOS 64bit,并且自Unity4.6.2以后着重于IL2CPP。

与MONO的区别在于,转换成中间语言IL之后,并不是通过MonoVM编译,而是利用IL2CPP将源码编译成C++语言,这用各自的Native C++ Compiler编译成二进制文件,再在IL2CPP VM上运行

il2cpp

采用IL2CPP的原因:

1.MONO受到的限制较大,如授权,专利等,不利于Unity的发展。

2.MONO VM维护成本较高,每个平台都需要维护,工作量非常大。

3.采用IL2CPP效率比MONO提高较多。

 

举例如下,新建Unity项目,仅用OnGUI写一个Label。

用C#的语句为:

   void OnGUI()
   {
      GUI.Label(new Rect(0,0,Screen.width,Screen.height),"Hello IL2CPP");
   }

再采用IL2CPP发布到IOS后,可以看到C#中的函数转变为如下代码。

Native文件夹是经过IL2CPP机制生成的文件代码。

unity-il2cpp