Game|Unity 3D游戏编程自学#3——Unity 3D初步

1.开始 在创建的项目文件夹中,各个子文件夹的作用:
Assets:保存游戏所需资源。
Library:保存当前项目运行所需要的库。
ProjectSettings:保存项目设置信息。
Temp:保存临时数据。

面板布局:设置为Default。
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片


软件界面介绍:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片


左上是层级(Hierarchy)面板,用于显示当前场景有哪些资源,可在此为场景添加资源。
上面这个是场景(scene)面板,用于预览当前场景。
下面这个是项目(project)面板,用于管理项目资源。
右侧这个是属性(Inspector)面板,用于查看、编辑物体和项目资源的具体信息。
场景(scene)是Unity 3D中的一个基本概念,是一种资源,保存于Asserts文件夹中。Ctrl+N可新建场景,Ctrl+S可保存当前场景。
每个新建场景时都会自带两个物体:摄像机和光源。

2.观察 在场景面板的右上角有一个三位坐标轴,其中红色的X轴代表右方,绿色的Y轴代表上方,蓝色的Z轴代表前方,可称其为世界坐标轴。点击相应坐标轴可切换到该轴的视角去观察。
坐标轴下方为显示模式:Persp或者Iso(点一下可切换)。Persp为透视模式,物体显示近大远小,Iso为正交模式,远近物体一样大。
每个3D物体有各自的坐标轴,在创建的时候其坐标轴与世界坐标轴一致,若物体旋转后可能就不一致了。
然而在修改物体的时候,可以切换物体的坐标轴为世界坐标轴:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

右边的Global按钮意为当前选中物体的坐标轴是与世界一致的,若点一下这个按钮,变为Local,这个时候物体坐标轴就是自身的。
按F键可以聚焦于物体(也可双击其在Hierarchy面板中的文件名),方便观察。
所有在Hierarchy面板中的物体(包括摄像机和光源)都可以在Inspector面板上令其“隐形”:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

将复选框上的勾去掉即可,此时该物体并没有消失,仅仅是隐形了。(在Hierarchy面板上其文件名也会变暗)
点击Scene面板右侧的Game面板,可以预览游戏运行时的情况,中上处的播放键可以预览游戏运行情况。(此时所有编辑、修改都无效)
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

摄像机:
决定游戏运行时我们所看场景的角度,Camera有个立体区域,称为视锥体,物体要在这个区域内才能在游戏运行时被看到。
可在Camera的Inspector面板中的Clipping Planes中修改该区域的大小,在该面板的Projection中可以调整摄像机的拍摄模式。
(Perspective相当于坐标轴中的Persp,Orthographic相当与Iso)
点击Hierarchy面板中的Main Camera可以调整摄像机的位置,Scene面板右下角也会出现一个预览界面。
在游戏开发时我们可能会调整到一个合适的角度去编辑,若想摄像机应用于此位置,可点击摄像机,然后Ctrl+Shift+F。
在预览时我们可以发现远处的虚空是天空,可在Camera的Inspector面板中的Clear Flags中修改。(虚空为Skybox,纯色为Solid Color)
光源
可在Hierarchy面板右键创建。
默认的光源为方向光(Directional Light,为一束平行光),在其对应的Inspector面板可调节其属性:
Type:灯光类型,有Directional(方向光)、Spot(聚光灯)、Point(点光源)。
Color:光的颜色
Intensity:灯光强度
Shadow Type:阴影类型,有Soft Shadows(软阴影,较为柔和),Hard Shadows(硬阴影,会有锯齿)和No Shadows。
此外,点光源还有Range(光照范围)、聚光灯还有Spot Angle(范围角)等属性。

3.3D模型创建与修改 基本功能
在层级面板中右键可创建3D模型(3D Object),里面有:
Cube:立方体
Sphere:球
Capsule:胶囊体
Cylinder:圆柱
Plane:平地
然后在面板的左上角有以下几个键可以调整这些物体:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

1.手型按钮用于调整用户所看场景的视角,右键可进行旋转。实际上还有另一种视角调整方法:鼠标滚轮缩放,中键移动,Alt+左键旋转,Alt+右键缩放。
2.四方的箭头按钮用于调整模型位置,可以沿线拉动,也可以沿着某一面拉动(效果是:平行于该面移动)。
3.旋转按钮用于旋转模型,同样可以沿线旋转和沿面旋转。
4.缩放按钮用于调整模型大小,可以沿X、Y、Z三轴等比例缩放。
5.第2、3、4按钮功能的综合。
这些按键的快捷键从左到右分别是Q、W、E、R、T、Y。
复制物体:Ctrl+C粘贴物体:Ctrl+V前两个综合:Ctrl+D
材质球(Materials)与贴图(Textures)
用于编辑物体材质、显示效果等。一般会在Assets中建立Materials以及Textures的文件夹存储这些文件。
材质球文件的后缀名为.mat。一个材质球决定一系列的颜色、纹理,往往一个材质球应用于一类模型中。
材质球的使用:
点击材质球属性面板中的Main Maps下的Albedo(漫反射贴图)前的圆点,将对应的贴图应用即可。更高级会使用到Shader(着色器)来调整材质球的属性。
若要将某个材质球上的材质应用于某个物体上,直接将材质球拖到该物体(或者拖到Hierarchy面板上对应物体文件名处)即可。
可调节材质球中纹理的密度:Main Maps下Tiling的值,数值越高,纹理越密。(密到一定程度,就看不出纹理了)
材质球的属性一旦更改,可立即应用于所有采用该材质球的物体上。
空物体和父子关系
在层级面板中可以创建空物体(Create Empty),它相当于文件夹,里面可以放置其他的3D Project。
比如说我要创建一个椅子模型,需要多个Cube,为了方便同一管理,可将这些Cube全部放在一个命名为Chair的空物体中,这样可以统一管理、编辑。
正常物体也可被当作“文件夹”,此时它与别的物体就存在一个父子关系(充当“文件夹”的物体为父)。
编辑子物体,父物体不会与之一同改变,但改变父物体,其所有子物体会跟着变化。
预制体(Prefab)
事先做好的物体,可在游戏开发中大量重复利用。
在Assets文件夹中创建Prefabs文件夹,预制体的后缀名是.prefab。
可将Hierarchy面板中做好的物体直接拖入Prefabs文件夹中,使其成为预制体。
将Prefabs中的预制体直接拖入Hierarchy面板从进行应用。
预制体在Hierarchy面板中文件名是蓝色的,非预制体是白色的,且预制体的Inspector面板中多了一个Perfab选项。
若对某个预制体进行了二次编辑,可以点击其右侧Inspector面板中Prefab的Apply,应用于所有预制体(包括Asssets文件夹中的)。
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

组件(Component)
每个物体都是由多个组件构成的,组件在Inspector面板中:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

例如Cube由五个组件构成,有些组件是可选的(可以不用,例如Mesh Renderer,把其复选框中的勾去掉)。
组件控制物体的属性,例如Transform组件,有Position、Rotation、以及Scale,分别确定物体的位置、旋转角度、大小。
Position、Scale中的数值单位为米,Rotation的单位为度。(例如X后面为30,意为以X轴为轴旋转30°)。
小技巧:按住X、Y或Z,然后左右拖动,可以微调数值。
若想重设这些数值,可以点击组件最右边的“齿轮”,里面有Reset选项。
组件也是一种类,每当物体挂载了组件后,系统会自动为我们实例化对象。

4.脚本(Script) 基本特性
控制游戏运行逻辑的一种特殊组件,Unity 3D支持C#和JavaScript,但C#为主流。
脚本也是一种资源,先在Assets中创建名为Scripts的文件夹,然后再文件夹中创建C# Script,脚本的后缀名为.cs。
双击相对应的脚本,会打开编辑器(本人电脑为Visual Studio 2017)对脚本进行编辑。
若想将脚本应用于某个物体,直接把脚本拖到Hierarchy面板上的该物体处即可。(也可拖到该物体的Inspector面板上)
脚本中有两个方法:Start和Update,Start中的命令在游戏开始时仅执行一次,而Update中的命令会重复执行(每帧一次,每秒60帧)
一个简单的语句:Debug.Log():相当于Console.WriteLine(),可在括号里面放一段字符串,将这些内容输出到Unity 3D的控制台中。
在Project面板旁边是Console(控制台),可以看到游戏运行时的脚本输出信息,其中有三个按钮:
Clear:清除信息。
Collapse:折叠相同信息,仅更新信息条数。
Clear on Play:运行时清除上次运行产生的信息。
在Update方法之下,其实还有一种方法:FixedUpdate,与Update不同的是,Update是按帧刷新,而每一帧的渲染所用时间可能不同,FixedUpdate是按时间刷新,该方法常用于物体间物理事件的处理(如碰撞)。
在Unity 3D的Edit—Project Setting—Time中的Fixed Timestep可以调整FixedUpdate的时间间隔。

5.物体移动与碰撞 获取键鼠输入
Input.GetKey():按下某键后持续返回True,直到你抬起。
Input.GetKeyDown():按下某键的瞬间返回True。
Input.GetKeyUp():抬起某键的瞬间返回True。
括号里面可以填入一个枚举类型KeyCode,例如,KeyCode.A就指键盘上的A。
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片
对应的控制台输出:Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

鼠标的输入与之相似:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

括号内直接填数值即可,0代表左键,1代表右键,2代表中键。
控制物体移动
物体中的所有组件都是类,当组件挂载在物体上后,运行时游戏引擎会自动实例化对象。
我们所编写的脚本其实也是一种类,但这个类相当于这些物体的大脑,可以控制器组件。
命令:gameObject.GetComponent<>(),用于引用某物体的组件,尖括号中填写组件名称,返回该组件。
如果我们想控制物体移动,需要用到Transform组件,则首先需要在Start方法中调用到Transform:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

在Transform这个类中有一个用于移动物体的无返回值的方法:Transform.Translate(Vector3,Space)
Vector3表示3位向量,用于指示移动方向(Vector3.forward、Vector3.back、Vector3.left、Vector3.right)
Space为一个枚举类型,用于确定物体是相对自己的坐标轴移动(Space.Self)还是世界坐标轴移动(Space.World)
则在Update中:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

然后依次把S、D、W的功能完善,就可以了。
注意:若感觉物体移动过快,可以在Vector3后面乘以0.1f减速
刚体
使物体具有重力,并能与其他刚体间发生物理反应。
选中相应物体,在Component中找到Physics选项,添加Rigidbody组件,该组件有以下几个参数:
Mass:物体质量,默认为1(kg)。
Drag:空气阻力,默认为0。
Angular Drag:角阻力,物体受到扭曲力时的空气阻力(当物体旋转下落时受到的横向的空气阻力)
Use Gravity:是否使用重力。
刚体移动:
首先在脚本中要引用到RigidBody组件:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

刚体移动的方法:Rigidbody.MovePosition(Vector3),该方法默认是相对世界坐标轴移动的。
其中Vector3参数的格式为:当前位置+移动方向
例如:

if (Input.GetKey(KeyCode.A)) { cubeRigidbody.MovePosition(cubeTransform.position + Vector3.left*0.1f); }

所以在Start方法中还要引用Transform组件。
同样,若移动过快,可在Vector3中乘以0.1
Rigidbody.MovePosition和Transform.Translate功能看似一样,实际上有所不同,后者一般仅仅用于物体的空间上移动,但前者加上了物理效果,其效果更像“走路”。
碰撞体
若要使两个物体之间可以发生物理碰撞,则这两个物体都要有碰撞体组件(Collider)。该组件可在Component的Physics中可添加(其实在创建3D Object时会自动创建)
物体仅有刚体组件而没有碰撞体组件是没有意义的,这样的物体会穿透任何东西,一路往下掉。
一般会将场景中无法穿透的障碍物设为无刚体的碰撞体。
碰撞体组件有以下属性:
Center:碰撞体的中心(相对于物体的坐标,一般在物体的中心,这个也是物体的重心)
Size:碰撞体的大小,如果这个Size超过模型显示的地方,模型以外的地方也会产生碰撞反应(相当于该物体产生了一个无形的力场)
这里也说明一下,我们看到的物体(颜色,纹理),其实是Mesh Renderer组件的作用,该组件只是将物体让用户“可视”,物体其他的属性还需别的组件实现。
碰撞体有多种:Box Collider、Sphere Collider……这些碰撞体仅形状不同而已,不同的3D Object对应不同的碰撞体(实际上你可以往Cube上套一个Sphere Collider),这里比较特殊的是Mesh Collider(网格碰撞体),该碰撞体非常精细,一般用于复杂物体(例如崎岖不平的山地)。
刚体的受力
方法:Rigidbody.AddForce(Vector3,ForceMode),其中Vector3和之前的一样确定方向(该方法是相对于世界坐标系移动的),ForceMode为枚举类型,有以下四种:
Acceleration:加速度
Force:普通的力,最常用,常用于模拟真实物理情况。
Impulse:冲击力,用于瞬间的发力。
VelocityChange:速度的变化。
例如,我通过鼠标左键发射一枚子弹:
if (Input.GetMouseButtonDown(0)) { bulletRigidbody.AddForce(Vector3.forward*1000,ForceMode.Force); }

除了AddForce,还有相对于自身坐标系移动的AddRelativeForce这个方法,其他参数两者都是一样的。
使用AddRelativeForce移动球体时,球体不会一直加速出去,而是会原地来回移动,因为球体滚动后,其自身坐标系也发生改变,下一帧力的作用方向也就改变了,从而产生这种现象。
碰撞检测
方法:OnCollisionEnter、OnCollisionExit、OnCollisionStay(这三个方法与Start和Update同级)
分别在:碰撞开始的瞬间、碰撞结束的瞬间、碰撞时启用(与Input.GetKey类似)。
这三个方法均包含一个参数:Collision的类,用于返回与当前物体相撞的物体的信息。
代码示例:
void OnCollisionEnter(Collision coll) { Debug.Log(coll.gameObject.name); }

相撞瞬间被撞物体的名字会在Console中显示,其他两个方法类似。
触发检测
在物体的碰撞体组件中可以将该物体的碰撞体调整为触发器:勾选上Is Trigger即可:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

这里可以调整触发范围(比如说,我想把该物体设置为自动感应门,其触发范围会在该物体之前)
若物体的碰撞体调为触发器,则其他物体可以直接穿过它,所有有关Colli sion的方法、函数也不会触发。
触发检测:OnTriggerEnter、OnTriggerExit、OnTriggerStay(功能与上述类似)
这些方法的参数仍然是一个Collision类,与碰撞检测一样。
旋转
方法:Transform.Rotate(Vector3,float)
其中,Vector3指定沿哪个轴转动,float表示旋转角度。 例如,按下E键开门:
if (Input.GetKeyDown(KeyCode.E)) { doorTransform.Rotate(Vector3.up, 90); }

Vector3.up表示沿Y轴正方向转动(forward、down、left、right等分别对应其他轴,均可使用)
物体自身坐标轴的原点是其中心点,但门这样的物体是不会绕自身中心点旋转的,因此可通过父物体的方式将门的中心点移动到一侧。
多个物体共同中心点的设置:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

Global左侧的按钮有两个状态:Pivot和Center。
在Pivot状态下选中多个物体,共同中心点是最后点选的物体的中心点,若是Center状态,则共同中心点位于各个物体中心点的中心。
自动旋转门
结合触发器使用。首先要加添加一个空物体作为触发器。(不能把门设置为触发器,防止其他物体穿越)
为该物体添加Box Collision,调整好触发范围后:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

然会用脚本在DoorTrigger中调用到使Door旋转的方法:
首先要查找到提供旋转功能的脚本:
每一个脚本也是一个类,可以被其他脚本调用。
对于触发器:
private DoorRotate doorR; //调用使门旋转的脚本 void Start() { doorR = GameObject.Find("DoorF").GetComponent(); } //注意区分:GameObject是一个静态方法,与之前用的gameObject不一样,该方法用于得到被旋转的对象(即门) void OnTriggerEnter(Collider coll) { if (coll.gameObject.name == "Person")//要使人来了才自动开门,其他物体一律不开 { Debug.Log("In"); doorR.OpenDoor(); } }void OnTriggerExit(Collider coll) { if (coll.gameObject.name == "Person") { Debug.Log("Out"); doorR.CloseDoor(); } }

对于门,把OpenDoor和CloseDoor完善即可:
public void OpenDoor() { doorTransform.Rotate(Vector3.up, 90); } public void CloseDoor() { doorTransform.Rotate(Vector3.down, 90); //这里参数也可以是:Vector3.up,-90 }

6.模型渲染 决定物体显示效果的组件: Mesh Filter和Mesh Renderer
Mesh Filter(网格过滤器)用于决定物体形状(方块、球……)
Mesh Renderer(网格渲染器)决定物体的阴影效果、材质球等,其中:
Cast Shadows:是否显示该物体的阴影
Receive Shadows:是否显示其他物体投射到该物体上的阴影

7.标签(tag) 为方便管理模型,可为模型添加标签:在Inspector面板中操作。
Unity 3D自带多个标签,但也可自定义。
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

可用以下静态方法批量得到同标签的物体:GameObject.FindGameObjectsWithTag(String)
string为标签名,该方法返回GameObject类的数组。
注意:另外一个方法GameObject.FindGameObjectWithTag的Object后面没有s,是对单个物体使用的。
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

批量更改游戏物体属性:(例如,所有物体在按W键后向上移动2米)
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

其中,中间那句话是之前属性定义和GetComponent的合并写法。
该脚本可以应用于被移动物体本身,也可以用于其他物体。

8.游戏打包发布 File—Build Settings,然后选择发布平台以及要发布的场景以及发布者信息(Player Settings):
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

之后打包出来的文件有:
Game|Unity 3D游戏编程自学#3——Unity 3D初步
文章图片

其中最下面那个exe是可删除的,运行游戏点击MoveDemo.exe,Data文件夹存放游戏数据。

【Game|Unity 3D游戏编程自学#3——Unity 3D初步】本文部分内容来自擅码网(http://www.mkcode.net)Unity 3D课程,经本人学习、整理得来,若有错漏,欢迎指正!

    推荐阅读