Unity3D默认函数的执行顺序

1. 正常情况下的顺序

  • Awake()
  • OnEnable()
  • OnLevelWasLoaded() // (only on scene changes)
  • Start()

A simple test with 3.5.2 revealed, most concurrent functions (well, at least the ones I tested: Awake, Start, OnEnable, FixedUpdate/Update/LateUpdate) abide by the execution order defined for the scripts. The execution order of OnLevelWasLoaded is not affected by that, and therefore cannot be influenced by the user. This could be considered a bug.

The order of the four methods of a script related to initialization is always:

  • Awake()
  • OnEnable()
  • OnLevelWasLoaded() // (only on scene changes)
  • Start()

However, if your script was disabled in the first place(via Script.enabled=false), this order changes to:

  • OnLevelWasLoaded() // is now called first, before Awake()! (only on scene changes)
  • Awake()
  • [OnEnable()/Start() are not executed until the script is actually enabled]

In addition, note that Awake() and OnEnable() calls are connected/interleaved. Meaning, assuming a particular, user-defined execution order A and B with A<B,

  • each individual script of type A will execute its Awake(), immediately! followed by its OnEnabled()
  • then all scripts of type B will do the same
  • then all OnLevelWasLoaded() will be executed, in a (presumably) fixed but unpredictable order (assuming this scene was freshly loaded - otherwise this step is skipped completely)
  • then all Start() will be executed, in the order A,B

In particular, this means that OnEnable() of type A will be executed before Awake() of type B, while OnEnable() of type B will be executed after Awake() of type A. This overview explains it more clearly:

  • Awake() of Type A, instance 1
  • OnEnable() of Type A, instance 1
  • Awake() of Type A, instance 2 // order of instances cannot be influenced
  • OnEnable() of Type A, instance 2 // order of instances cannot be influenced
  • Awake() of Type B
  • OnEnable() of Type B
  • OnLevelWasLoaded() of Type ? // order cannot be influenced
  • OnLevelWasLoaded() of Type ? // order cannot be influenced
  • Start() of Type A
  • Start() of Type B

EDIT: Hm, this is a total mess. If DontDestroyOnLoad() is activated for such a script, this will geteven more complicated, and the order changes yet again to:

  • [Awake() is never called again, only the very first time]
  • OnEnable()
  • OnLevelWasLoaded() // as opposed to being called before OnEnable(), when DontDestroyOnLoad() isnot activated
  • [Start() is never called again, only the very first time]

EDIT2: In addition, when DontDestroyOnLoad() is active, the user-defined execution order is no longer abided by!, neither by OnEnable(), nor by OnDestroyOnLoad().

EDIT3: WAH! I'm gonna stop testing now, this is a neverending story... As @Noisecrime noticed, there is actually another bug, where user-defined execution order is overriden if the script has an OnEnable() function!

Script A has OnEnable, Script B has not:

  • Awake() of Type A
  • OnEnable() of Type A
  • Awake() of Type B

Script B has OnEnable, Script A has not:

  • Awake() of Type B
  • OnEnable() of Type B
  • Awake() of Type A // after Type B!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值