
Unity-底层原理
Unity是如何实现跨平台的 首先,我们要知道Unity,Mono,.Net 三者的关系。需要简单说一下.Net。 .Net拥有跨语言,跨平台性。 跨语言:就是只要是面向.Net平台的编程语言,用其中一种语言编写的类型就可以无缝的在另外一种语言编写的应用程序中互操作。 跨平台:一次编译,不需要任何代码修改,应用程序就可以运行在任意在.Net实现的平台上跑,即代码不依赖于操作系统,也不依赖硬件环境。一个.Net程序运行的核心在于.Net CLR(公共语言运行时,或者称为.Net 虚拟机,类似java虚拟机的概念),为了让.Net程序在其他平台(目前只能在.Net 平台,windows系统)上跑,微软官方还推出了在其他平台上(MacOs,Linux)跑的 .Net的实现,就推出了.Net Core。 然而,Unity引擎需求也是需要跨平台,支持多语言(C#,Js,Boo)。就参考微软开发.Net Core的概念,于是,推出了Mono. 到这里,基本说明了.Net 与Mono和Unity的联系关系,其实没啥关系。做游戏都知道,肯定需要跨平台,不能只支持一种平台,不然每个对应的平台做出一种对应的编译器,那真的会累死。所以对于跨平台的需求,对于游戏开发而言,很重要。Unity的架构需求设计当然也需要这个特性。参考.Net依托CLR来实现设计思路,于是Mono就出来了。 Mono介绍 Mono是一个由Xamarin公司所主持的自由开放源码项目。 Mono的目标是在尽可能多的平台上使.net标准的东西能正常运行的一套工具,核心在于“跨平台的让.net代码能运行起来“。 Mono组成组件:C# 编译器,CLI虚拟机,以及核心类别程序库。 Mono的编译器负责生成符合公共语言规范的映射代码,即公共中间语言(Common Intermediate Language,CIL),我的理解就是工厂方法实现不同解析。 IL的全称是 Intermediate Language,很多时候还会看到CIL(特指在.Net平台下的IL标准)。翻译过来就是中间语言。 它是一种属于通用语言架构和.NET框架的低阶的人类可读的编程语言。 CIL类似一个面向对象的汇编语言,并且它是完全基于堆栈的,它运行在虚拟机上(.Net Framework, Mono VM)的语言。 工作流程: 通过C#编译器mcs,将C#编译为IL(中间语言,byte code) 通过Mono运行时中的编译器将IL编译成对应平台的原生码 编译器 C#编译器mcs:将C#编译为IL Mono Runtime编译器:将IL转移为原生码。 三种转译方式: 即时编译(Just in time,JIT):程序运行过程中,将CIL的byte code转译为目标平台的原生码。 提前编译(Ahead of time,AOT):程序运行之前,将.exe或.dll文件中的CIL的byte code部分转译为目标平台的原生码并且存储,程序运行中仍有部分CIL的byte code需要JIT编译。 完全静态编译(Full ahead of time,Full-AOT):程序运行前,将所有源码编译成目标平台的原生码。 Unity跨平台的原理 Mono运行时编译器支持将IL代码转为对应平台原生码 IL可以在任何支持CLI,通用语言环境结构)中运行,IL的运行是依托于Mono运行时。 IOS不支持jit编译原因: 机器码被禁止映射到内存,即封存了内存的可执行权限,变相的封锁了jit编译方式。 JIT编译 将IL代码转为对应平台原生码并且将原生码映射到虚拟内存中执行。JIT编译的时候IL是在依托Mono运行时,转为对应的原生码后在依托本地运行。 优点: 构建应用非常快 由于Mono的JIT(Just In Time compilation ) 机制, 所以支持更多托管类库 支持运行时代码执行 必须将代码发布成托管程序集(.dll 文件 , 由mono或者.net 生成 ) Mono VM在各个平台移植异常麻烦,有几个平台就得移植几个VM(WebGL和UWP这两个平台只支持 IL2CPP) Mono版本授权受限,C#很多新特性无法使用 iOS仍然支持Mono , 但是不再允许Mono(32位)应用提交到Apple Store IL2CPP介绍 IL2CPP 是 Unity一种新的脚本后处理(Scripting Backend)方式,针对.Net平台编译输出的IL(中间语言)进行处理。 ...