Version: 2020.3

描述

Awake 在加载脚本实例时调用。

在加载场景时初始化包含脚本的活动 GameObject 时,或者在将先前非活动的 GameObject 设置为活动时,或者在初始化使用 Object.Instantiate 创建的 GameObject 之后,都将调用 Awake。 在应用程序启动前使用 Awake 来初始化变量或状态。

在脚本实例的生存期内,Unity 仅调用 Awake 一次。脚本的生存期持续到包含它的场景被卸载为止。如果重新加载场景,Unity 会再次加载脚本实例,因此会再次调用 Awake。如果以叠加方式加载场景多次,Unity 会加载多个脚本实例,因此 Awake 会被调用多次(每个实例一次)。
对于放置在场景中的活动 GameObject,Unity 在初始化场景中的所有活动 GameObject 后调用 Awake,因此可以安全地使用 GameObject.FindWithTag 等方法查询其他 GameObject。
Unity 调用每个 GameObject 的 Awake 的顺序是不确定的。因此,你不应依赖一个 GameObject 的 Awake 会在另一个 GameObject 的 Awake 之前或之后调用(例如,你不应假定由一个 GameObject 的 Awake 设置的引用可在另一个 GameObject 的 Awake 中使用)。相反,你应该使用 Awake 在脚本之间设置引用,并使用 /Start/(在所有 Awake 调用完成后调用)来回传递任何信息。
始终先调用 Awake,然后才调用任何 Start 函数。这让你可以对脚本的初始化进行排序。即使脚本是活动 GameObject 的禁用组件,也将调用 Awake
Awake 不能充当协程。

注意:请使用 Awake 来代替构造函数进行初始化,因为组件的序列化状态在构造时是未定义的。 与构造函数一样,仅调用 Awake 一次。

using UnityEngine;

public class ExampleClass : MonoBehaviour { private GameObject target;

void Awake() { target = GameObject.FindWithTag("Player"); } }

对于未激活的 GameObject,调用 GameObject.SetActive 可以将其激活。


以下两个示例脚本 Example1Example2 协同工作,展示了调用 Awake() 的两个时间点。
要重现该示例,请创建具有两个 GameObject(Cube1 和 Cube2)的场景。通过取消选中 Inspector 左上角的复选框(Cube1 将变为不可见),将 Example1 作为脚本组件分配给 Cube1,并将 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() { Debug.Log("Example1.Awake() was called"); }

void Start() { Debug.Log("Example1.Start() was called"); }

void Update() { if (Input.GetKeyDown("b")) { print("b key was pressed"); } } }

Example2。这将导致调用 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; } } } }