资源的访问
资源的使用
在脚本中,也可以引用一个资源。比如
- AudioClip ,音频文件
- Texture,纹理贴图
- Material ,材质
使用步骤:
- 准备音效文件,预览
- 添加脚本 AudioTest.cs。其中添加资源
public AudioClip audioSuccess;
- 引用音频资源
- 使用 API 播放音频
AudioSource.PlayOneShot( clip );
,用于播放音效
1 | public class AudioTest : MonoBehaviour |
资源数组
在脚本中,也可以定义一个数组变量。
例如,一个音乐盒,存了多首歌曲。public AudioClip[ ] songs;
创建一个音乐盒,点鼠标随机切换。挂载MusicBox.cs
1 | public class MusicBox : MonoBehaviour |
注意:获取随机数API
index = Random.Range( min, max );
用于在 [min, max) 中随机抽取一个数,不包含 max
练习
三色球,制作一个变换颜色的小球
创建Sphere,挂载ThreeColorBall.cs
1 | public class ThreeColorBall : MonoBehaviour |
也可以使用其他办法,比如直接修改 Material 的 Albedo 颜色
定时调用
定时调用
定时调用 Invoke* ,即一般所谓的‘定时器’
继承自 MonoBehaviour :
Invoke (func , delay)
,只调用一次InvokeRepeating (func, delay, interval)
,循环调用IsInvoking (func)
,是否正在调度中CancelInvoke (func)
,取消调用、从调度队列中移除
传入的参数中,func ,函数名是一个字符串 ( 反射机制 )
创建一个小球,挂载SimpleLogic.cs
1 | void Start() |
运行游戏,可以看到DoSomething()方法启动1s后执行了
修改代码,使用InvokeRepeating方法
1 | void Start() |
运行游戏,可以看到启动1s后第一次执行,后面每隔2s执行一次
实现:弹跳小球
1 | public class SimpleLogic : MonoBehaviour |
定时与线程
InvokeRepeating 定时调用,并没有创建新的线程
Unity引擎的核心是单线程的,不必考虑线程、并发、互斥
通过控制台打印可以发现,Start() 、Update()、以及定时调用的方法,是在同一个线程
1 | void Start() |
可以发现线程id相同
注意点
- 重复调用。每次 InvokeRepeating ,都会添加一个新的调度(多调度一次)
- 调用相关API
IsInvoking ( func )
,判断 func 是否在 Invoke 队列CancelInvoke ( func )
,取消 func 的 Invoke 调用CancelInvoke ( )
,取消当前脚本的所有 Invoke 调用
注意:在 Invoke 时,一般要避免重复调用。实现方法
1 | if (!IsInvoking(func)) |
练习1
实现一个红绿灯,其中,红灯,4秒;绿灯,4秒;黄灯,1秒
1 | public class LightLogic : MonoBehaviour |
练习2
实现速度渐变的效果
1 | public class FanLogic : MonoBehaviour |
向量
向量概述
向量 Vector3 ,三维向量 ( x , y , z )
向量,即有方向的量
- 方向
- 长度
向量的长度 : L = √(𝑥^2+𝑦^2+𝑧^2)
求向量长度的API: 使用 Vector3 类中的 magnitude 属性
1 | Vector3 v = new Vector3(3, 0, 4); |
单位向量:长度为 1 的向量。
例如,
Vector3 v1 = new Vector3(1, 0, 0);
Vector3 v2 = new Vector3(0.6f, 0.8f, 0);
标准化 Normalize :缩放一个向量,使其长度为 1
例如,
(3 , 4, 0 ) → ( 0.6, 0.8, 0 )
(2 , 2, 0 ) → ( 0.707, 0.707 , 0 )
(1, 0, 0 ) → ( 1, 0 , 0 )
标准化API : 使用 Vector3 中的 normalized 属性
1 | Vector3 v1 = new Vector3(2, 2, 0); |
几个常量
Vector3.zero 即 ( 0, 0, 0 )
Vector3.up 即 ( 0, 1, 0 )
Vector3.right 即 ( 1, 0, 0 )
Vector3.forward 即 ( 0, 0, 1 )
向量的运算
- 向量加/减法,即 x y z 三个分量分别相加/减。例如
1 | Vector3 a = new Vector3 (1, 3, 0); |
- 向量乘法,分为 3 种:
- 标量乘法 b = a * 2
- 点积
c = Vector3.Dot(a, b)
- 差积
c = Vector3.Cross(a, b)
其中,一般用标量乘法 ,即对每一个分量相乘
Vector3 是值类型,可以直接赋值。例如
1 | Vector3 a = new Vector(1, 1, 0) ; |
不能设为 null ,
1 | // 正确 |
向量测距
向量测距,用于求两物体间的距离。例如,
1 | Vector3 p1 = this.transform.position; // 自己位置 |
Vector3.Distance(p2, p1)
,也可以求距离
1 | Vector3 p1 = this.transform.position; |
注意:物体间的距离,确切的说是轴心点之间的距离。应检查确认物体的轴心点。
向量的使用
Vector3 可以直接作为脚本的参数
1 | // 定义速度向量 |
通过设置Speed的XYZ可指定移动方向
预制体
预制体概述
预制体 Prefab ,即预先制作好的物体。使用预制体,可以提高开发效率
例子:导出 RacingCar 资源包
- 在 Prefabs 目录下,是预制体资源,后缀是 *.prefab
- 用预制体来构造物体
注意:
- 使用预制体 Prefab ,可以快速创建物体
- 在 Prefab 资源中,包含了的所有数据
预制体的创建
预制体的创建:
- 先制作好一个样本节点
- 做好以后,直接将需要保存的节点拖到 Assets 窗口,则自动生成一个 *.prefab 资源
- 原始物体不再需要,可以删除
注意:
- 在导出 prefab 资源时,应该将依赖文件一并导出。
- prefab 只是记录了节点的信息。
- prefab 文件中不包含材质、贴图数据,仅包含引用
预制体的实例
Prefab Instance ,由预制体创建得到的对象
特征 :
- 在 Hierarchy 中,节点图标不同
- 在 Hierarchy 中,右键菜单 | Prefab
- 在 Inspector 中,上下文工具 | Prefab
注意:
- Prefab Instance 和原 Prefab 之间存在关联
- 右键节点,选择 Prefab | Unpack ,则解除关联,成为普通物体
- Prefab 中,具有多级节点 / 父子关系的预制体是常见情况
预制体的编辑
*.prefab 相当于是一个模板,可以再次编辑
第1种方式:单独编辑
- 双击 Prefab ,进入 单独编辑 模式
- 编辑节点和组件
- 退出,完成编辑
第2种方式:原位编辑
- 选择 Prefab Instance
- 在检查器中 Prefab-Open
- Context显示三种模式:Normal:普通视图 / Gray:灰色视图 / Hidden:隐藏编辑节点以外的所有节点
- 三种模式仅选中物体可编辑,其余物体无法编辑
- 编辑节点
- 退出,完成编辑
第3种方式:覆盖编辑
- 选择 Prefab Instance
- 直接在场景中编辑
- 编辑完后,检查器-Prefab-Overrides,Apply/Revert ,应用/放弃编辑
注意:右键Prefab节点-Prefab-Unpack后,可解除节点与预制体的关联