一、万物之源——MonoBehaviour类
MonoBehaviour 是 Unity 中所有脚本的基类,它提供了一系列用于实现游戏对象行为的功能。通过继承 MonoBehaviour,用户可以创建自定义的脚本,以控制游戏对象的生命周期、响应事件和管理游戏逻辑。它具有以下主要功能:
生命周期管理:
MonoBehaviour
提供了一系列的事件函数(如Awake()
、Start()
、Update()
等),帮助开发者管理对象的生命周期。组件系统:Unity 使用组件化的设计,
MonoBehaviour
允许你将功能模块化,便于在不同的游戏对象之间重用代码。访问 Unity API:通过
MonoBehaviour
,可以直接访问 Unity 的许多功能,如物理引擎、渲染系统和输入管理。协程支持:
MonoBehaviour
支持协程,允许你在一段时间内执行代码,而不会阻塞主线程。
二、什么是脚本生命周期?
脚本生命周期是指 Unity 中 MonoBehaviour 脚本的执行顺序和时间点。了解脚本生命周期对于编写有效的游戏逻辑至关重要。以下是 MonoBehaviour 的主要生命周期事件函数及其顺序,具体其他事件函数的执行周期可以参考Unity说明文档的具体内容:
1. Awake()
- 调用时机:脚本实例被加载时。
- 用途:用于初始化变量或状态,通常在游戏对象启用之前执行。
2. OnEnable()
- 调用时机:对象启用时。
- 用途:可以在此处订阅事件或进行初始化操作。
3. Start()
- 调用时机:在第一次更新之前调用。
- 用途:用于进行一次性初始化,确保所有引用已设置。
4. Update()
- 调用时机:每一帧调用一次。
- 用途:处理每帧需要更新的逻辑,例如输入处理和对象移动。
5. FixedUpdate()
- 调用时机:每固定时间间隔调用。
- 用途:适用于物理计算(如 Rigidbody 的移动),因为它以固定频率执行。
6. LateUpdate()
- 调用时机:在所有 Update 调用之后。
- 用途:用于相机跟随等需要在所有其他更新后执行的操作。
7. OnDisable()
- 调用时机:对象禁用时。
- 用途:通常用于取消事件订阅或清理资源。
8. OnDestroy()
- 调用时机:对象销毁之前调用。
- 用途:用于释放资源或执行清理工作。
三、什么是时间函数?
事件函数是 Unity 中 MonoBehaviour 类提供的一组特殊方法,用于响应特定事件或条件。这些函数在特定的上下文中被自动调用,允许开发者实现游戏对象的动态行为。以下是一些常见的事件函数及其用途:
Awake():在脚本实例被加载时调用。常用于初始化变量。
OnEnable():当游戏对象启用时调用。适合进行事件订阅或初始化。
Start():在第一次更新之前调用。用于一次性初始化。
Update():每帧调用一次。处理每帧需要更新的逻辑,如输入处理和移动。
FixedUpdate():每固定时间间隔调用。适合物理计算,例如 Rigidbody 的移动。
LateUpdate():在所有 Update 调用之后调用。用于相机跟随等需要在其他更新后执行的操作。
OnDisable():当对象被禁用时调用。用于取消事件订阅或清理资源。
OnDestroy():在对象销毁之前调用。用于释放资源或执行清理工作。
物理和碰撞事件:
- OnCollisionEnter():当物体发生碰撞时调用。
- OnCollisionExit():当物体停止碰撞时调用。
- OnTriggerEnter():当物体进入触发器时调用。
- OnTriggerExit():当物体离开触发器时调用。
用户输入事件:
- OnMouseDown():当鼠标点击游戏对象时调用。
OnMouseUp():当鼠标释放点击时调用。
四、代码范例
在前一篇博客中我们介绍了协程(Coroutine),在本范例中我们将通过代码理解Unity中关键事件函数的执行流程。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ExecutionSequence : MonoBehaviour
{
int counter;// start is called before the first frame updatevoid start()
// Start is called before the first frame update
void Start()
{
StartCoroutine("myCoroutine");
print("start ends.");
}
// Update is called once per frame
void Update()
{
if (counter < 10) print("frame:" + counter++);
}
IEnumerator myCoroutine()
{
print("step1");
yield return null;
print("step2");
print("step3");
}
}
执行顺序如下:
- 首先,
Start
方法首先被调用,协程myCoroutine
启动,控制台输出 “step1” 。 - 执行完yield return null; 退出协程函数,暂停在下一帧(下一次Update执行后)继续执行。控制台输出 “start ends.”。
Update
方法第一次调用,counter
由0开始计数,首先在控制台输出”frame: 0″ 。- 当
Update
方法运行到下一帧时(第二次调用),控制台输出”frame: 1″ 。 - 协程继续执行,控制台打印输出 “step2” 和 “step3″。至此协程所有内容执行完毕。
- Update 方法再次调用,直到 counter 达到 9。
