# 事件函数

> Event functions are a set of built-in callbacks which you can implement on your MonoBehaviour-derived scripts to respond to core Engine events related to physics, rendering, input, scene loading, and object lifecycles.

事件函数是所有 [MonoBehaviour](/engine/6000.0/manual/scripting/get-started/fundamental-unity-types/class-mono-behaviour.md) 脚本组件都可能收到的一组预定义回调。回调由各种 Unity 编辑器和引擎事件触发，包括：

* [常规帧和物理更新](#regular-updates)
* 对象[生命周期事件](#initialization-events)，例如场景中对象的初始化和销毁
* [UI 事件](#gui-events)
* [物理事件](#physics-events)

在 `MonoBehaviour` 派生的类中实现适当的签名方法，以允许游戏对象对源事件做出反应。

请参阅 [MonoBehaviour](/engine/6000.0/script-reference/unity-engine/mono-behaviour.md) 脚本 API 参考页面以查看可用回调的完整列表，这些回调列在 **Messages** 下。本节的其余部分将对一些关键的事件函数组进行概述。

## 常规更新事件

游戏很像动画，其动画帧是动态生成的。游戏编程中的一个关键概念是在渲染每帧之前改变对象的位置、状态和行为。[Update](/engine/6000.0/script-reference/unity-engine/mono-behaviour/update.md) 函数是 Unity 中此类代码的主要位置。在渲染帧之前以及在计算动画之前会调用 `Update`。

```lang-csharp
void Update() {
	float distance = speed * Time.deltaTime * Input.GetAxis("Horizontal");
	transform.Translate(Vector3.right * distance);
}
```

物理引擎也采用与帧渲染类似的方式以离散时间步骤进行更新。在每次物理更新之前都会调用一个称为 [FixedUpdate](/engine/6000.0/script-reference/unity-engine/mono-behaviour/fixed-update.md) 的单独事件函数。由于物理更新和帧更新不会以相同频率进行，所以如果将物理代码放在 `FixedUpdate` 函数而不是 `Update` 中，此代码将产生更准确的结果。

```lang-csharp
void FixedUpdate() {
	Vector3 force = transform.forward * driveForce * Input.GetAxis("Vertical");
	rigidbody.AddForce(force);
}
```

为场景中的所有对象调用 `Update` 和 `FixedUpdate` 函数之后以及计算所有动画之后，如果能进行其他更改，有时也会很有用。这种情况的示例如下：

* 摄像机应始终对准目标对象的时候。必须在目标对象移动后调整摄像机的方向。
* 脚本代码应覆盖动画的效果的时候。例如，使角色的头部朝向场景中的目标对象。

可使用 [LateUpdate](/engine/6000.0/script-reference/unity-engine/mono-behaviour/late-update.md) 函数来处理这些类型的情况。

```lang-csharp
void LateUpdate() {
	Camera.main.transform.LookAt(target.transform);
}
```

## 初始化事件

能够在游戏运行过程中发生的任何更新之前调用初始化代码，这通常是很有用的。在第一帧之前或对象物理更新之前需要调用 [Start](/engine/6000.0/script-reference/unity-engine/mono-behaviour/start.md) 函数。场景加载时会为场景中的每个对象调用 [Awake](/engine/6000.0/script-reference/unity-engine/mono-behaviour/awake.md) 函数。请注意，虽然各种对象的 `Start` 和 `Awake` 函数的调用顺序是任意的，但在调用第一个 `Start` 之前，所有 `Awake` 的实例都要完成。这意味着 `Start` 函数中的代码可以利用先前在 `Awake` 阶段执行的其他初始化。

## GUI 事件

Unity 有一个系统用于渲染场景中主要操作的 GUI 控件，并响应对这些控件的点击。此代码的处理方式与正常的帧更新有些不同，因此应将此代码置于定期调用的 [OnGUI](/engine/6000.0/script-reference/unity-engine/mono-behaviour/on-gui.md) 函数中。

```lang-csharp
void OnGUI() {
	GUI.Label(labelRect, "Game Over");
}
```

此外，还可以检测场景中出现的游戏对象上发生的鼠标事件。使用此功能可以定位武器或显示当前在鼠标指针下的角色的相关信息。一组以 `OnMouse` 为前缀的事件函数（例如 [OnMouseOver](/engine/6000.0/script-reference/unity-engine/mono-behaviour/on-mouse-over.md)、[OnMouseDown](/engine/6000.0/script-reference/unity-engine/mono-behaviour/on-mouse-down.md)）可以让脚本对用户的鼠标操作做出反应。例如，如果指针位于特定对象上时按下鼠标按钮，则会调用该对象的脚本中的 `OnMouseDown` 函数（如果存在）。

## 物理事件

物理引擎将通过调用该对象的脚本上的事件函数来报告对象的碰撞情况。在进行接触、保持接触和中断接触时，将调用 [OnCollisionEnter](/engine/6000.0/script-reference/unity-engine/mono-behaviour/on-collision-enter.md)、[OnCollisionStay](/engine/6000.0/script-reference/unity-engine/mono-behaviour/on-collision-stay.md) 和 [OnCollisionExit](/engine/6000.0/script-reference/unity-engine/mono-behaviour/on-collision-exit.md) 函数。对象的碰撞体配置为触发器（即碰撞体只检测某物何时进入而不作出物理反应）时，将调用相应的 [OnTriggerEnter](/engine/6000.0/script-reference/unity-engine/mono-behaviour/on-trigger-enter.md)、[OnTriggerStay](/engine/6000.0/script-reference/unity-engine/mono-behaviour/on-trigger-stay.md) 和 [OnTriggerExit](/engine/6000.0/script-reference/unity-engine/mono-behaviour/on-trigger-exit.md) 函数。如果在物理更新期间检测到多次接触，可能连续多次调用这些函数，因此会将一个参数传递给函数，从而提供碰撞的详细信息（位置、进入对象标识等）。

```lang-csharp
void OnCollisionEnter(Collision collision) {
	if (collision.gameObject.tag == "Arrow") {
		ApplyDamage(10);
	}
}
```

## 其他资源

* [MonoBehaviour](/engine/6000.0/manual/scripting/get-started/fundamental-unity-types/class-mono-behaviour.md)
* [事件函数执行顺序](/engine/6000.0/manual/scripting/object-oriented-development/event-handling/execution-order.md)
* [MonoBehaviour API 参考](/engine/6000.0/script-reference/unity-engine/mono-behaviour.md)
