1. 调用时机
Awake 是 Unity 脚本生命周期中最早被调用的方法之一。它在脚本实例被创建后立即调用,甚至在游戏对象在场景中被激活(SetActive (true))之前就会执行。这意味着无论游戏对象的初始状态是激活还是未激活,Awake 方法都会被触发。
和Reset一样,它也不会在初始的脚本中被创建,我们依然可以自己创建。
private void Awake()
{
print("Awake调用");
}
在游戏开始运行的时候Awake会执行一次。
如果运行游戏之前GameObject是非激活状态(SetActive (false)),那么Awake将不会执行,将Game Object设置为激活状态时会重新调用Awake。需要注意的是,Awake在一个生命周期里只会调用一次且仅调用一次。
2. 功能用途
其实可以对比一下类的构造函数,Awake和构造函数在用法上是大差不差的,主要就是用来初始化。特别是那些在整个生命周期中保持不变的值。例如,如果有一个脚本用于控制敌人的行为,可以在 Awake 方法中初始化敌人的最大生命值、攻击力等属性。
public int maxHealth = 100;
public int attackPower = 10;
void Awake()
{
// 在这里初始化变量,这些变量在整个生命周期中基本保持不变
}
再一点就是,可以获取游戏对象自身或者其子对象上的其他组件引用。例如,获取一个刚体组件(Rigidbody)和一个碰撞器组件(Collider),以便后续处理物理碰撞和运动。
private Rigidbody rb;
private Collider col;
void Awake()
{
rb = GetComponent<Rigidbody>();
col = GetComponent<Collider>();
}
3. 注意事项
- 首先就是前面提到的,Awake在一个生命周期里只会调用一次且仅调用一次,所以要确保在这个方法中进行的初始化操作是完整的,避免在后续阶段出现未初始化的变量导致的错误。
- 再一个,由于 Awake 方法调用时间很早,一些依赖于游戏对象激活状态或者其他脚本完整初始化的操作可能无法在 Awake 中正确执行。例如,如果试图在 Awake 方法中访问另一个脚本的某个方法,而这个脚本的 Awake 方法还没有执行完,可能会出现意外的结果。
- 在 Awake 方法中获取组件引用时,如果组件不存在于游戏对象上,会返回 null。所以在使用这些引用之前,最好进行 null 检查,以避免空引用异常。
private MeshRenderer mr;
void Awake()
{
mr = GetComponent<MeshRenderer>();
if (mr != null)
{
// 进行与MeshRenderer相关的操作
}
}