一、添加脚本的顺序

这是一张官方的脚本顺序图

浅谈Unity的脚本执行顺序-LMLPHP

一般,当我们把脚本绑定在游戏对象上时,或者点击绑定好的脚本的reset按钮时,会调用Reset()

当我们初始化一个对象时,会先调用Awake()在调用OnEnable()

GameObject.instantiate(o);

start()在第一次调用update()前调用,有时候start()会在Awake(),OnEnable()执行完后立刻执行,处于同一帧

onDisable()和onDestroy()的执行顺序有点特别:

第一种情况:

  对于不同对象上的不同的脚本,执行是没有先后规律的,且必须成对执行(调用完了onDisable()必须再调用onDestroy())

  eg:

gameobject1:
    sc1.cs
    sc2.cs
gameobject2:
    sc3.cs
    sc4.cs
gameobject3:
    sc5.cs
    sc6.cs

gameobject1.sc1.onDisable()->gameobject1.sc1.onDestroy()->gameobject3.sc5.onDisable()->

gameobject3.sc5.onDestroy()

[如果按前面的规则的话,应该先执行gameobject3的脚本,但这里不是]

第二种情况:

在同一个对象的不同的脚本上,这两个方法按照脚本

在m_component中的索引按顺序执行的,而且不是成对执行,索引自小到大执行,最早加入的最早调用onDisable()和onDestroy()

gemeobject2.sc3.onDisable()->gameobject2.sc4.onDisable()->

gameobject2.sc3.onDestroy->gameobject2.sc4.onDestroy()

这里这些脚本先依次调用onDisable()才调用onDestroy()。

二、如何自定义多个脚本的执行顺序

浅谈Unity的脚本执行顺序-LMLPHP

 划重点:在unity里面可以点击edit->project settings->Script->Execution Order中自定义脚本执行顺序,

当我们没有设置脚本执行顺序时,脚本按照Default Time的标准执行(你可以把unity里面hireachy里面添加对象和在inspector里面添加脚本

视作一个栈,按照先进先出原则,优先执行后添加的对象的先添加的Script。

可以单击+号添加对象到执行列表中

1是脚本的执行顺序,当你的值execution order越小时,越先执行,在default time上方的在执行default time前执行,在default time下方

的在default time后执行

上面的设置,是通过修改每一个脚本对应的meta文件(去自己的代码目录看一下)的excution order来实现的。

浅谈Unity的脚本执行顺序-LMLPHP

 三、脚本执行顺序的本质

在我们的场景文件.unity,场景文件是一个YAML文档

浅谈Unity的脚本执行顺序-LMLPHP

 每一个脚本对应一个fileid,fileid越小越有先执行

 4.运用

如果你的脚本A会用到另一个脚本B中的某一个对象c,为了防止你在B初始化之前去调用c,出现空指针,你必须让脚本B在A之后挂载(这样B就会先初始化),

还有一个很重要的地方,你必须把对象c的初始化写在脚本B的Awake()方法里面,因为start()并不是在初始化就立刻调用的,而是在当前更新一帧时,start()

会在update()第一次调用前调用一次,这样的话如果你把对象c的初始化写在脚本B的start()方法里面,很有可能所有脚本的awake()都跑完了,对象c却没有初始化,

这样就出现了空指针。因此,把对象c的初始化在脚本B的awake()方法,而把调用对象c写在脚本A的start()足够安全

06-11 10:52