Unity是什么

首先读者需要清楚地知道,Unity是一种工具或者说软件,至目前成书之时已退出5.0版本。也可以说Unity是一款优秀的3D游戏引擎,其对于底层图形接口的封装为开发者省了不少事,极大地缩短了传统游戏开发应有的开发周期和人力成本。

但是读者不能认为Unity是一门语言。Unity提供了图形化的编辑工具,以及它的编译器。前者我们在本书中约定为狭义的Unity(即本书以后提及这个图形化编辑工具时也简单地称为Unity)。后者本书直接称其为IDE。

Unity的跨平台特性

但凡是关于Unity的书籍必然会讲一讲Unity的跨平台特性,既然老生常谈了读者不妨自己利用网络资源了解了解,简单来讲正是由于Unity强大的跨平台特性,给予了我们一种先在某个平台推出测试版,再快速扩展到全部平台的方式。

Unity支持的编程语言

狭义来讲,Unity直接支持3种脚本语言编写游戏脚本,分别是C#、Javascript与Boo。

后面两种语言由于其语法之诡异程度以至于普遍接受的语言是C#。广义来讲,Unity还有用来编写Shader的ShaderLab语言,以及GPU编程语言CG。再广义来讲由于Unity支持dll的import,因此能够支持更多的语言编写dll以供脚本调用。

Unity世界的快速认识

在可视化编辑器中,我们安装好Unity后便会看到一个已经生成的场景、主摄像机。先前瞻性地讲一讲场景、主摄像机与具象的游戏内容。部分涉及的知识会在下一章节“Unity的预备知识体系”中详细讲解。

一个Unity工程由多个场景(Scene)组成,每个场景可包含多个摄像机(Camera)和多个游戏体。多个摄像机以深度(Depth)来区分,深度最浅的摄像机为主摄像机,也只有一个摄像机是主摄像机。不同深度的摄像机仿佛从不同的视角观察我们的场景,最终游戏画面看到的画面由各个摄像机的深度为优先条件进行组合展现。最容易理解的例子是我们玩很多游戏的时候游戏画面上都有一个半透明的小地图,实际上就是两个摄像机的组合,一个摄像机从主角身后跟随主角观察场景,另外一个摄像机从主角正上方俯视场景,并只描绘场景中的特殊元素并抽象为一个个的点。

多个游戏体之间的关系更是错综复杂,在Hierarchy视图中我们可以组织游戏体之间的树形惯性,后面我们还会通过游戏脚本(组件)为游戏体之间添加隐形的联系。也有内置的组件,例如关节组件,为游戏体之间构建内在关联。写到这里作者认为可以抛出GameObject的概念了:

在所有的Untiy项目中,最基本的单元叫做GameObject,即游戏对象,即使我们并没有进行游戏的开发,同样也是操作各种各样的GameObject。

最基本的单元是GameObject,一个工程由场景、摄像机、游戏体、以及脚本(组件)组成,而场景和脚本却不属于游戏对象。场景是比较特殊的,但是比较好理解。那么摄像机是一种特殊的游戏对象。他没有外观,他的作用是为用户观察场景提供一个视角。设想现实生活中两个摄像机面面相对,应该互相能看到彼此。而Unity中两个摄像机面面相对,没有其他游戏体那么什么也没有。

没有外观的游戏对象除了摄像机,还有一个,叫做空游戏对象(Empty Object)。这个东西我们后面也会灵活地应用。

在学习之前就必须牢记的一点:Unity最特殊的地方在于任何代码必须依附于一个GameObject才会被游戏引擎调用执行。

抛出这句话,希望读者能在学习之初就能牢记,以便防止写了一大段代码,运行出来完全没反应以至于找了一下午都没发现原因的情况出现(作者就干过这种事情)。熟悉其他程序开发的读者应该都会有入口的概念。在Unity中代码的入口其实就是GameObject,代码通过依附而被引擎执行,与我们一般写完代码需要Link呀、Make呀之类地不太一样。

组件——component

前面提到脚本的地方,我都细心地用括号标注了组件上去。细心的读者应该就能理解,其实脚本就是一种组件。本书约定组件和脚本的概念无区别。

一个游戏对象没有组件,是无法想象的,那就是它没有任何外观和属性。在Unity中也无法找到这样的情景,因为任何对象都有一个无法删除的组件叫做Transform组件。最简单的空游戏对象(Empty GameObject)即是由一个Transform组件构成的。因此我更倾向于认为游戏对象(GameObject)是一个个容器,容器中用来放组件。

写到这里我当然又要自然地抛出Transform组件的概念了:

重要组件——Transform

当我们创建一个游戏对象(GameObject)之后,必然出现且唯一且无法删除的一个内置组件。他反映了我们的游戏对象的坐标、旋转度与缩放程度。

由于Unity是一个3D游戏开发引擎,因此transform组件的3个属性皆有三个维度。

在Unity中,要经常以向量的思维来思考。因为Unity中的标量实在少的可怜,大部分的常理与变量不是矩阵就是向量。就连颜色,他也是一个4元向量,红绿蓝(为什么不是红黄蓝?)分别是颜色向量的3个分量RGB,第4元为不透明度Alpha。

因此transform组件由3个向量构成,分别是坐标向量Position,旋转向量Rotation与缩放向量Size。关于这3个向量的特性后面我们还会在空间矩阵变换的时候更深入地讨论。

关于维度、向量、坐标系的讨论我会在下一章节《Unity预备知识体系》中更详细地提及,读者也可以先行查阅相关资料。

那么除了Transform这个重要组件,Unity内置的组件还有很多,我们再介绍两个相对重要的:

形状组件MeshRenderer与材料组件Matierial

形状组件,我们又称为网格组件。在计算机表达三维图形的时候,都是由一个个的三角形拼接而形成复杂的图形,就像我们鸟巢的房顶一样,像一个三角形网,因此我们往往把它叫做网格。在3D建模软件中也是如此。Unity内置的形状只有几种:球体、立方体、圆柱体、胶囊体等,我们往往也只能创建这些基础形状。一般来讲游戏开发中我们要用的形状非常之多,且往往复杂,但是无需多虑,这些将交由大家以后的同事——游戏美工在3DMAX/Maya等软件中将模型文件制作好,我们只需直接导入即可创建一个例如漂亮美女的3D形状。

材料往往模拟着现实世界中的物体表面的颜色信息。例如玻璃近乎没有颜色,且透明。例如金属有特殊的光泽。皮球的表面凹凸不平。镜子可以反射光线。不同的游戏对象有各自的材料设定,所以我们需要创建合适的matierial组件依附给它。这是狭义的材料,我在这里为它起个名字叫做外观材料。

在Unity游戏开发中,我们模拟出来的世界不能光有视觉效果,往往还需要符合物理规律,例如我驾驶一辆赛车,赛车碰到赛道的边缘应该是要翻车而不是继续行驶。Unity中的材料除了狭义的外观材料,还有物理材料。我们后面也会详细提及。物理材料往往表达着物体的密度、质量、弹性系数等物理属性。是肉眼不能观察到的一些物理属性。

接下来是我之前的系列文章的主题Shader了,这里做一个简单的介绍,具体知识可以读一读该系列文章。

材料的灵魂——Shader着色器

着色器为我们的外观材料提供一种数学计算方式。也就是告诉计算机怎样模拟出不同材料的视觉效果。初学阶段我们只需要学会使用几种基本的内置shader即可:漫反射Diffuse、镜面反射Specular、视差漫反射与镜面反射Parallax Diffuse/Specular。

本章的最后,我们讲一讲图形、动画以及游戏之间的区别和联系。

点动成线,线动成面,面动成体。这是我们义务教育中数学就讲过的东西。讲的玄乎一点,其实它表达的是低维度的图元沿更高维度的轴线进行运动形成高维度的图元。

动画出现的最开始其实就是一页页画连续翻动,由于视觉停留现象让人感觉画面在连续运动。也就是说图形图形沿着时间维度进行运动从而形成动画,简而言之连续的图像形成动画。

而动画加上用户操作的控制,才能成为最简单的游戏。当然复杂的游戏还有很多动画没有的特性。例如贪吃蛇。一条蛇在不停地向前冲,如果没有任何方向键的输入,那么就像一个给定要的动画片一样。当出现用户输入上下左右且程序分别改变蛇的前进方向的时候才能避开障碍物、墙壁、自己的身体,朝食物的方向前进。这样才能称之为游戏。