Unity 在启用脚本实例加载时调用 Awake
。
Unity 在以下情况下调用从 MonoBehaviour
派生的脚本的 Awake
:
使用 Awake
在应用程序启动之前初始化变量或状态。
Unity 在脚本实例的生命周期中只调用一次 Awake
。脚本的生命周期持续到包含它的场景卸载为止。如果场景再次加载,Unity 将再次加载脚本实例并再次调用 Awake
。如果场景以增量方式加载多次,Unity 将加载多个脚本实例,并且每个实例将调用一次 Awake
。
对于放置在场景中的活动 GameObject,Unity 在场景中所有活动 GameObject 初始化完成后调用 Awake
,因此您可以安全地使用 GameObject.FindWithTag 等方法来查询其他 GameObject。
Unity 调用每个 GameObject 的 Awake
的顺序是不确定的。因此,您不应该依赖于一个 GameObject 的 Awake
在另一个 GameObject 之前或之后被调用。例如,您不应该假设一个 GameObject 的 Awake
设置的引用可以在另一个 GameObject 的 Awake
中使用。相反,您应该使用 Awake
设置脚本之间的引用,并使用 Start(它在所有 Awake
调用完成后被调用)传递任何信息。Awake
始终在任何 Start 函数之前调用。这使您能够对脚本的初始化进行排序。即使脚本是活动 GameObject 的禁用组件,也会调用 Awake
。如果脚本组件的 Awake
抛出异常,Unity 将禁用该组件。 Awake
不能充当协程。
使用 Awake
而不是构造函数进行初始化,因为组件的序列化状态在构造时是未定义的。与构造函数一样, Awake
也只调用一次。
using UnityEngine;
public class ExampleClass : MonoBehaviour { private GameObject target;
void Awake() { target = GameObject.FindWithTag("Player"); } }
当对 GameObject 调用 GameObject.SetActive 时,可以激活非活动 GameObject。
以下两个示例脚本 示例 1 和 示例 2 协同工作,并说明了调用 Awake() 的两个时机。
要重现示例,请创建一个包含两个 GameObject Cube1 和 Cube2 的场景。将 Example1 作为脚本组件分配给 Cube1,并将 Cube1 设置为非活动状态,方法是取消选中 Inspector 左上角的复选框(Cube1 将变得不可见)。将 Example2 作为脚本组件分配给 Cube2,并将 Cube1 设置为其 GO
变量。
进入播放模式:按空格键将执行 Example2.Update 中的代码,该代码将激活 Cube1 并导致 Example1.Awake() 被调用。
using UnityEngine;
// Make sure that Cube1 is assigned this script and is inactive at the start of the game.
public class Example1 : MonoBehaviour { void Awake() { // Prints first Debug.Log("Example1.Awake() was called"); }
void Start() { // Prints second Debug.Log("Example1.Start() was called"); }
void Update() { if (Input.GetKeyDown("b")) { // Prints Last if "b" is pressed Debug.Log("b key was pressed"); } } }
示例 2. 这将导致 Example1.Awake() 被调用。空格键用于执行此操作
using UnityEngine;
public class Example2 : MonoBehaviour { // Assign Cube1 to this variable GO before running the example public GameObject GO;
void Awake() { Debug.Log("Example2.Awake() was called"); }
void Start() { Debug.Log("Example2.Start() was called"); }
// track if Cube1 was already activated private bool activateGO = true;
void Update() { if (activateGO == true) { if (Input.GetKeyDown("space")) { Debug.Log("space key was pressed"); GO.SetActive(true); activateGO = false; } } } }