三教杯项目问题1——关于Awake、Start执行顺序的问题

缘由

刚接触了一周Unity就匆匆忙忙参加了学校的一个一周限时游戏开发的比赛,结果由于对Unity的不熟悉导致出现了各种奇奇怪怪的问题。本来计划好的很多功能最终因为要解决冒出来的各种问题导致只实现了很小一部分。现在“作业”终于提交上去了,抽空来整理一下遇到的各种问题。

我做的是一个射击类型的游戏。既然是射击类型的游戏那肯定避免不了要使用对象池。然而奇怪的是,在游戏开始之后虽然对象池内已经生成了预设体,但是Unity却抛出了找不到对象池中对象的问题。通过各种排查发现,原来是调用的时候对象池还没有初始化,而产生这个问题的原因是把对象池的初始化语句放在了Start中导致的,把初始化语句挪到Awake中完美的解决了问题。那么Unity中Awake、Start他们的运行和顺序到底是怎样的呢?

分析

查看一下Unity官方的API吧。(以下是我自己翻译的,仅供参考)

Awake()

当加载脚本实例时调用Awake。

Awake被用来在游戏开始前初始化任何变量或游戏状态。在脚本的生命周期中只调用一次Awake。当所有对象被初始化之后调用Awake,因此你可以安全的让其他对象使用例如GameObject.FindWithTag。每个GameObject的Awake的调用是随机的。因此,你需要使用Awake建立脚本之间的引用,使用Start来相互传递信息。Awake总是在启动任何函数之前被调用。这允许你对脚本的初始化进行排序。Awake不能扮演coroutine的角色。

Start()

Start在脚本启用之后,第一次调用任何Update方法之前的帧调用。像Awake函数一样,在脚本的生命周期中只会调用一次Start。然而,无论脚本是否启用,当初始化脚本对象时都会调用Awake函数。如果初始化时没有启动脚本,Start可能不会和Awake在相同的帧上被调用。

在调用任何对象的Start之前,将会对场景中所有对象调用Awake函数。这在对象A的初始化代码需要依赖对象B已经初始化的情况下是非常有用的。B的初始化需要在Awake完成,而A的初始化需要在Start中完成。

当对象在游戏过程中被实例化时,他们的Awake函数在场景对象的Start函数已经完成时启动。

其实官方的API中说的已经很清楚了,所有对象初始化之后都会统一先调用Awake(这个调用顺序是随机的),在所有初始化对象的Awake调用都结束之后才会调用Start!因此我们需要在Awake中对对象进行必要的初始化,然后在Start中进行相互间的使用,否则极有可能会返回找不到对象的异常。

猜你喜欢

转载自blog.csdn.net/yyyynnnn1993/article/details/82976483