2026.03.12 · 生命周期

Awake、OnEnable、Start:我后来才分清的三件事

刚写 Unity 时,我把初始化全塞进 Start。对象默认启用时,这通常能跑通。后来做对象池,预制体反复开关,问题就来了:有的字段只初始化一次,有的却要每次亮起来都重绑。

我现在的分工

void Awake()
{
    _rigidbody = GetComponent<Rigidbody>();
}

void OnEnable()
{
    _health = _maxHealth;
    GameEvents.OnPlayerHit += HandleHit;
}

void OnDisable()
{
    GameEvents.OnPlayerHit -= HandleHit;
}

订阅一定要在 OnDisable 里退订。对象被关掉后如果事件还指着它,下次再启用,或者场景卸载时,很容易出现空引用。

执行顺序

两个脚本都挂在同一个物体上时,Awake 的先后并不保证按你在 Inspector 里看到的顺序。需要严格先后时,我会用 Script Execution Order,或者让一方在 Start 再去问另一方。

备忘:OnDisable 不等于销毁。池子里休眠的对象不会走 OnDestroy,所以清理工作不能只写在 Destroy 里。