转自:http://www.jiandaima.com/blog/archives/945.html
是如何输出到多平台的?
我的第一篇文章,选择了一个不那么简单的主题,但是是我近期比较感兴趣的。这周,我和一个朋友,谈到了游戏开发和Unity3D,他问我,“为什么Unity可以输出到那么多的平台上?”我想了一下,试图组织语言,但是我尽然不能回答这个问题。我从来没有认真想过这个问题,所以,我开始做一些研究。
哪些人适合看这篇文章:如果你是一个开发者,对于 托管、本地代码,执行环境和不同平台这些概念有一定的了解,这篇文章是为你准备的。如果你是3D、2D美术,或者对于这类工作比较好奇的人,我非常抱歉,你可以停下来了,并接受一个可怕的答案:它就是这样神奇。你可以跳到本文的最后两段,结论在那里。如果你还是很好奇,你可以试一试继续读下去。
我们开始讨论这篇文章的话题:Unity3D可以说是市面上最流行的游戏开发引擎了。它非常友好(相信我,学习一些教程之后,15岁的孩子也能使用它)。它现在有Window和MacOs X版(Linux现在还在实验阶段),本文最重要的一点:它可以输出在几乎所有的设备上。我不是在开玩笑,看一下官网上的列表:
iOS
Windows Phone
BlackBerry
Windows
Windows Store Apps
Mac OS X
Linux
Their native Web Player
PS 3
Xbox 360
Wii U
PS 4
Xbox One
Tizen
SamsungTV
PS Vita
Gear VR
Oculus Rift
它适合无数的设备和环境。如果你还不知道Unity3D,可以试一下。免费的版本可输出Mac OX, Linux, Window, iOS, Android, BlackBerry, Web Player,SamsungTV, WebGL, Tizen,WindowPhone。相当不错,试一下。(遗憾,我并没有收收到Unity官方的广告费,仅仅只是我觉得它真是太赞了。)
更新:Jashan在评论里指出,这篇文章,我只把重点放在了脚本上,所以,我决定多写一点关于Unity3D如何输出其他特性到如此多的平台上。阅读下面一段,你会注意到,尽管使用Unity技术是一个伟大的工作,它依然依赖于许多公司帮助它将一些特性引入Unity。在新平台中发布时,Unity的开发人员会一个一个地检查量否支持每个特性,如果是的话,完成这些特性的时间会大幅度降低。现在,让我们看一下这些主要要特性。
图形
我们从图形开始。Unity提供大量的图形API:OPenGL, OpenGL ES,WebGL,Metal和DirectX,每一套API都有一个目标平台。OpenGl用得最广,它可以运行在MacOS X,iOS,Linux还有Windows上。OpenGL ES适合一些移动设备,Andriod和iOS最为常见。WebGL是基于浏览器的图形应用和游戏的希望,它可以淘汰掉Flash插件和Unity的Web Player。Metal是苹果上新的图形API,它可以兼容最近的iOS设备和一些Californian公司的电脑。最后,DirectX,是微软自己的的图形API,兼容Windows, Windows Phone、XBOX。所以,UT的开发者花了大量的时间在图形上,但大部是用于将这些工具整合进引擎中,而不是从头开始写自己的API。
物理引擎
轮到物理引擎了,Unity信赖一个工具:Nvidia的PhysX,Unity发布的每一个平台,它都可以支持。毫无疑问,它是市面上最好的物理引擎,从每一版的游戏引擎开始,它就是值得信任和高效的,那时PhysX还被叫做Novodex,也没有被Nvidia收购。不同平台使用同一物理解决方案的主要原因是它的一致性:在不同的设备上,所有的碰撞、运行都必须有相同的行为,否则,某些平台就会更受欢迎。
灯光
更说一次,Unity依赖于终端工具实现灯光,不论是烘焙出来的灯光还是实时灯光。在以前,进行烘焙灯光用Autodesk的Beast,现在它被 Enlighten取代。在新的5.X版本中,它可以同时实现时实全局光照和烘焙灯光。
网络层
2014年,Unity内部发布了UNET(Unity的网络层),是Unity自主研发的多玩家的网络方案。过去,一些网络解决方案开始普及,最有名的就是Photon。新的工具包括两个方面,网络层的API(有API高低级别)和有偿的多人服务,不同于上面描述的图形、物理引擎和灯光,由于这是一个内部项目,UT必须移值代码到所有支持的平台上去。
最后:脚本
给那些还不了解Unity的人,Unity让我们使用C#和UnityScript脚本(EWW),不需要任何转换或是专门的工具,将我们的游戏输出到前面列出的平台上。好像很简单。引出了一个问题:如何做到的?我以为只要我停下来,想一想就可以得到答案,但即使我有一些Unity工作原理的认识破,我也不能回答为什么。所以,我问了这些年我最好的朋友(google)如本文标题的这个问题。这样说吧,我没有得到最好的反馈,后来,我找到了原因:我问了错误的问题。
本文中真实的明星是:Mono。我知道Mono对于Unity是很重要,但它远远超过了我所想。让我们从这里开始:Mono究竟是什么?根据官网:Mono是跨平台,开源的.net开发框架。还是有一些疑惑,让我们深入Mono的历史。
2000年微软发布了“基于inernet标准的新的平台”.Net的框架,Xamarin公司有一个叫Miguel de Icaza的人非常喜欢.NET,想开发Linux的版本,微软的.net不支持Linux(到现在还是不支持)和一些其他的非窗口平台。他干脆决定创建他自己的环境,Mono工程在2001开源。Mono由一个开源项目,把net框架被带入了其他平台,包括C#编译器和CLR(公同语言运行库)。从历史来看,Mono一开始就被放在了.net之后。今天它不仅实在了.net的功能,还有一些外的功能。总结一下,Mono是一个开源项目,用C/C++实现了.Net的开发框架,今天可以运行在一大堆平台上。
现在,我们停止讨论Mono,转到Unity上来。在Unity中,我们是如何用脚本编程?用C#或是UnityScript,这里又引出一个问题,如果我们用C#编程,为什么Unity游戏可以运行在如此多的平台上?难道在上不需要JAVA,在iOs上不需要用Object-C来代替C#?难道Unity编不同平台的游戏时不需要平台本地代码?如此多的问题。
我们从最后一个问题开始。不需要,Unity编不同平台的游戏不需要本地代码。听上去太疯狂了。Android不用JAVA?不用。你也可以用本地代码开发(用C/C++),但是没有人想那样做,对吗?那就是Mono做的事情。
现在我们说一说最重要的问题:没有C#的运行环境,为什么我的Android设备可以运行一个C#写的游戏?Mono运行了它。但是,我并没有在我的设备上安装Mono呢?所以,基本问题是:Mono是如何进入我的设备的?Unity编译的游戏(和用Mono开发的应用)运行了一个Mono环境。你疯了没有?我现在不能证明它,但是Xamarin在这里“How it works”声明过,非常有道理:
使用C#写你的APP,从C#中直接调用平台的API。Xamarin编辑器捆绑了.NET运行库,输出成一个ARM可执行文件,再打包进iOS和应用中。
这又产生了另一个问题:一个MONO发开APP附带了整个框架?答案可以在同一网页中找到:编辑Link的时候,在框架中没有使用的类会被剥离出来。所以,只是部分框架被绑定在你的APP中,如果你想了解更多的它是如何工作,访问网页 Developer Center。
所以,Mono是这里的上帝,它为Unity游戏提供了.Net框架。这是为什么,你使用C#编出来的游戏,能在如此多的平台上运行的原因。这是我的第一贴,我希望我能有更多的想法来更新博客。不论你喜欢或者不喜欢,或者某个地方有错,甚至你觉得这篇文章完全是胡扯,都可以请留言。
重要更新(2015年9月):IL2CPP技术改变了脚本后台工作的方式,淘汰了Mono的VM和AOT编辑器。
下面读什么?我写了一个新贴子,关于Unity3D在引擎之下是如何工作的,我们的代码是如何与引擎代码相交互的。