PETimer(一)
Awake和其他生命周期的区别
Awake调用的时机
脚本Awake
的内容只要挂载它的物体在场景中就能启用。
脚本Start
、Update
、LateUpdate
等的内容需要当前脚本的enable打开才能启用(这种脚本挂载时前面有一个“√”)
OnEnable、OnDisable调用时机
当一个脚本第一次调用时,先执行OnEnable
再执行Start
。之后脚本再次enable或disable只会执行OnEnable
和OnDisable
,不会调用Start
了
FixedUpdate的Timestep
FixedUpdate为固定帧率,在Project Settings——Time里面可以设定Timestep,默认0.02即为50帧
LateUpdate
一般用作摄像机跟随运算
FixedUpdate的调用
FixedUpdate
并不是一直保证每0.02秒运行一次,我们可以用下面的代码来测试:
1 | using UnityEngine; |
如果我们输出
Debug.Log("FixedDeltatime:" + Time.fixedDeltaTime.ToString());
它会固定是0.02秒
FixedUpdate
保证的是它的计算是和物理系统的计算同步,而Update
保证的是它的计算和渲染同步。
我们在Unity - Manual: Order of execution for event functions中可以看到,FixedUpdate
是个独立的更新循环。
在Update执行1次渲染帧之间,FixedUpdate
可能执行了0次、1次或许多次物理帧。假设我们的timestep
设为0.02,FixedUpdate
就要保证每一秒至多有50帧物理帧。
我们先假设物理系统执行非常顺利,而渲染比较卡的情况:
- 这种情况下一个渲染帧需要的时间(
Time.DeltaTime
)可能会超过物理帧规定的时间(Time.fixedDeltaTime
),这个时候就会出现一帧渲染帧之间,FixedUpdate执行了多次的情况
我们再假设渲染系统执行顺利,而物理系统比较卡的情况:
- 在这种情况下,如果在一个规定的物理帧(每0.02秒)中没有完成物理运算,那么执行渲染帧是没有意义的,所以Unity在Project Settings——Time里面添加了Maximum Allowed Timestep,默认是0.3333333,因为更高的timestep有更小的物理计算压力,可以保证在渲染时物理计算可以完成。
- 如果还是完不成,Unity会暂停物理计算,进行渲染,再在下一个物理帧时从暂停的地方继续运算,这样虽然会导致物理运算变慢,不过是可以接受的。
脚本执行顺序
在游戏中尽量在入口物体GameRoot
中进行全局初始化,以保证初始化顺序,也就是说只有GameRoot
脚本有Start
或Awake
方法,其他功能性脚本的初始化从Init
函数中进行。
GameRoot
1 | public class GameRoot : MonoBehaviour{ |
逻辑帧
Unity一个场景中的所有物体是在一个单线程(即主线程)串行更新的,在一次帧循环中,场景中的物体一个接着一个地完成各自的生命周期内的函数(实际情况并不完全是这样,在这里为了简化理解),我们参考场景其中一个物体,从它本身开始Update再回到它本身下一次Update的过程称为一次逻辑帧。
协程的一些要点
StopAllCoroutines
只能停止当前脚本内的协程。
StopCoroutine()
有多个重载,既能使用Coroutine
作为参数,又能使用IEnumerator
作为参数,还能使用字符串(传入方法名)
如果开启协程的物体,在协程中途Disable或Destroy,那么此物体的协程都会关闭,重新Enable不会继续协程