对Start()方法执行顺序的思考
Unity版本:Unity5.6.4f1
在Unity中,先执行Awake()方法,后执行Start()方法
有这样一个例子,
public class Item:MonoBehaviour { private UILabel name; //Item类的属性 void start() { //获取Item属性的代码 name = transform.Find("name").GetComponent<UILabel>(); }; void SetName() { //给Item的属性赋值 name = "Tom"; } }
public class UI:MonoBehaviour { void start() { //实例化Item,并调用Item.SetName 赋值 }; }
本例中,UI类在Start()方法中实例化Item,并用Item类的方法给其赋值,这样写会导致空指针错误。
其实际的执行顺序是 : UI.Start() → Item.Awake() → Item.SetName() → Item.Start()
在name初始化前就对其赋值导致出错。
这样,我们就知道,Start()方法并不是在Awake() 执行完成后立即执行的。
查阅官方文档,事件函数的执行顺序如下

在Start()调用前,会进行一次OnEnable的判断,也就是Inspector界面,组件旁的√ ,我们通常可以把勾去掉以阻止脚本的执行。

这个方法并不是完美的,上文的例子中,若禁用了Item脚本,Item.Start()不会执行,而Item.Awake() 和 Item.SetName() 依然会执行。
即禁用脚本并不能阻止Awake方法的执行,也不能阻止其他类调用该脚本的其他public方法。
PS:一个有趣的现象
当一个脚本中没有定义Start及后续事件函数时,脚本旁的√ 会消失,无法设置OnEnable,如下图)
无Start及后续事件函数的情况

有Start及后续事件函数

笔者第一次遇到这种情况时,还以为又是Unity的小毛病,重启了好几次
总结:
1,初期的架构很重要
2,坚持代码的风格可以有效防止错误,也能快速定位错误
3,为防止再次出现这种错误,决定以后统一写法,将初始化语句写入一个独立的函数,然后在赋值前调用,确保赋值前完成初始化。

浙公网安备 33010602011771号