怎么学Unity开发(四)

1. 组件介绍

组件对应的就是功能,每个游戏物体都可以看作是空物体 + 若干个具有特定功能的组件

1.1. 系统预置组件

在任意一个游戏物体的检查器里,可以找到“添加组件”按钮,里面的组件就是系统提供的预置组件

image-20220424224739091

1.2. 自行编写的脚本组件

当系统提供的组件无法满足需求时,通常就需要自己编写C#脚本作为自定义的组件

1.3. Transform组件

image-20220425080151814

无论什么游戏对象,在出生的时候都会自带一个Transform组件,即使是空对象也是如此

Tansform组件描述了当前对象在场景中的位置以及呈现的姿态等属性

2. 添加预置组件

image-20220425081137453image-20220425081217966

这两处都可以进行组件的添加

先准备一个空物体,然后加上一个Mesh Filter

image-20220425081419891

该组件可以选择一种网格的外观给当前的游戏对象,这里可以选一个Sphere

但是,仅仅选中网格,没有渲染器并不能够看见,因此继续添加一个Mesh Renderer组件

image-20220425081711169

这样,就可以看到这个物体了

image-20220429223038164

但是,现在没有为其添加材质,因此看起来与其他直接创建的球在外观上有些不一样,这里可以直接创建个材质加上

image-20220429223247506

这里选择这种默认材质,与平常创建的几何体用的是同款

这样,在外观上基本是保持一致了

3. 组件状态控制

在一些组件的面板上,会有这种复选框

image-20220429223618505

用来设置当前组件的启用或禁用

image-20220429223754185

并且在游戏物体上也有一个复选框,用于表示整个游戏物体的启用和禁用,组件当然是隶属于对应的游戏物体的

一旦禁用,游戏物体会被置灰,并且消失在场景当中

image-20220429224025924

由于被禁用,处于一种不可选中的状态下

4. 组件的复制粘贴

image-20220429224628173

可以通过复制组件组件从一个物体复制到另一个物体上

image-20220429225109751

然后在另一个物体上将组件粘贴为新组件,这样会将复制的组件作为一个新的组件添加到该物体上

除此之外,如果在原来的物体的组件上更新了参数的值,想要将这些参数的值更新的现在物体对应的那个组件上,可以同样执行组件的复制操作,只是粘贴的步骤有所不同

image-20220429225659762

在判断出组件相同的情况下,可以无需再创建一个新组件,只是将组件对应的参数的值更新的当前的组件中

5. 添加脚本组件

创建脚本组件往往是由于系统的组件无法满足业务的需求,创建方式也很简单

image-20220429230615612 image-20220429230454215

都可以直接新建或添加一个脚本组件

创建完脚本文件之后可以双击关联一下,这个时候会调起Visual Studio,打开对应的类

image-20220429231233829

类的名称要确保与脚本文件的名称一致,否则会出问题,在外部修改.cs文件的名称时,里面的类名并不会跟着变,因此一定要注意**.cs文件的名称需要与类的名称一致**

6. 脚本的生命周期

终于可以看代码了,直接打开之前的脚本组件对应的.cs脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hello : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{

}

// Update is called once per frame
void Update()
{

}
}

以上有两个最为常用的声明周期方法Start()Update()

为了了解其调用,需要使用Debug.Log()方法进行日志的输出,在控制台上打印调试信息,以此了解声明周期的调用

6.1. 概览

Awake()

1
2
3
4
private void Awake()
{
Debug.Log("Awake");
}

实际上,Awake()在生命周期中会是最早被调用的,像是刚刚出生、苏醒过来,并且生命周期当中仅调用一次

image-20220430173308088

可以看到,控制台中的打印信息,Awake()先于Start()输出

OnEnable()

组件激活后调用一次,如果组件处于启用,在Awake()之后会被调用

image-20220430174958558

由于当前的组件已被启用,因此在Awake()Start()之间插入了OnEnable()

Start()

OnEnable()之后调用,生命周期中只调用一次,通常处理初始化相关的操作,会在更新前被调用

FixedUpdate()

以固定的时间间隔进行刷新,这个间隔可以在项目设置中找到

image-20220430181429298 image-20220430181600540

更新所处的阶段是在Start()之后,每隔0.02s更新一次,这种更新无关性能,只是固定的时间间隔

Update()和LateUpdate()

这两个方法总是捆绑在一起,与性能有关,每一帧调用一次,时间间隔通常不等

image-20220430184932193

可以关注到,Update()LateUpdate()调用了相同的次数,LateUpdate()总是跟在Update()的后面

OnDisable()

该状态与OnEnable()正好相反,代表组件的禁用,组件改变禁用状态也会触发onEnale()onDisable()之间的切换

OnDestroy()

组件的生命周期中调用的最后一个方法,代表组价生命的终结

image-20220430193619744

将游戏物体从场景中删除,依次触发OnDisable()OnDestroy()

6.2. 多个脚本的场景

如果有多个脚本在组件上,这个时候如果需要控制执行的顺序应该怎样做呢?

image-20220430220915425

这两个脚本只做一件事:打印生命周期,可以发现在第一个脚本onEnable()结束后,第二个脚本才开始,但是可以发现,都是所有脚本的Awake()结束后,才会回调Start(),脚本根据类型回调,可以考虑通过这个来控制顺序

除此以外,如果想要更加有条理地控制脚本的顺序,也可以借助项目设置里面的功能对执行顺序进行控制

image-20220430222007877

将需要控制顺序的脚本放入其中,右边数字小的就先执行,也可直接进行拖拽,上面的总会是数字小的

image-20220430223443918

然后应用变更,就能够按照设置的顺序进行执行

7. 标记

7.1. 名称标记

image-20220430225257342

通过设置标记,方便找到物体或分类,效果就像是超市货架上的商品一样

image-20220430225404622

7.2. 标签

主要用作游戏物体的标识符,可以方便脚本对游戏物体进行获取以及判断

image-20220430225712550

也可以添加各种自定义的标签,标签不一定唯一,也可能表示一类对象

image-20220430230002583 image-20220430230054148 image-20220430230131048

7.3. 图层

相较于标签,图层相当于直接将游戏物体进行分组(通常是比较重要的类型)

image-20220430230353924

可以添加图层进行游戏对象分组,前几层一般是系统使用的,通常在Layer6开始添加,并且最多到Layer31

image-20220430230450759

在添加完图层后,可以将需要分到一起的游戏对象塞到对应的层中

image-20220430231133906

图层的一个常用的场景在摄像机对于内容的过滤方面

image-20220430231252034

通常情况下,Culling Mask是Everything,这样会把所有场景拍摄到其中

image-20220430231827519 image-20220430231921038

但是这个时候对于其中的图层进行取消选择,对应的游戏物体就不会出现在摄像机的视野当中了

image-20220430231803129