本文内的大致机制是个人凭借理解的经验之谈,也就是说如果我来写这个功能应该怎么写,不一定对,借鉴一下就行
文章目录
帧
Application.targetFrameRate (fps)
游戏实际的fps由Application.targetFrameRate决定,这个字段是可以自己设置的。设置好之后,游戏便会按照这个速率进行逐帧播放。
无论Time.timeScale是多少都不会影响帧播放的速度。
当然,不是每两帧之间的时间间隔都是一样的,所以才会存在Time.deltaTime。
Time.frameCount
这个参数存的是游戏开始到现在为止的总帧数。
游戏时间
Time.timeScale
Time.time的增长的速率倍数
Time.deltaTime
距离上一帧的时间差,受Time.timeScale影响。
大致机制: realDeltaTime*Time.timeScale。
Time.time
游戏开始到现在的时间(秒),受Time.timeScale影响。
大致机制: 每一帧增长Time.deltaTime。
Time.realtimeSinceStartup
游戏开始到现在的时间(秒),不受Time.timeScale影响。
大致机制: 当前时间减去游戏开始时间
Update
Update
每帧都会调用,由于帧不受Time.timeScale影响,所以Update调用的速率也不受Time.timeScale影响。
如果需要受Time.timeScale影响,最简单的便是在Update内使用Time.deltaTime。
LateUpdate
这个函数也是每一帧调用,但是是等所有Update执行完毕后再执行。
FixedUpdate
固定时间调用,例如每0.02秒执行一次。
内部应该是根据Time.time来执行的,所以受Time.timeScale影响。
大致机制: 如果Time.time大于某时刻,执行,并刷新时刻到下一个时刻。
调用的时间间隔可以在项目设置内修改:
听说挺耗费性能的不推荐使用。
生命周期
GameObject首次Active=true时
- Awake
- OnEnable
- Start
Active=true时每帧调用
- Update
- LateUpdate
非首次Active=true
- OnEnable
Active=false
- OnDisable
脚本被删除或者绑定的游戏对象被销毁
- OnDestroy
各个Update执行的顺序
协程
参考我的这篇博文https://jkchen.blog.csdn.net/article/details/110791595
其中与帧相关的或者WaitForSeconds是受Time.timeScale影响的。
WaitForSecondsRealtime则不受Time.timeScale影响。
减少Update内容执行的次数
比方说我需要检测鼠标下的对象,但是fps=30的时候难到一秒钟可以变化30次?
这种情况下我们可能只需要每0.5秒执行一次就可以了,所以在Update内加入
逻辑:
我的游戏Time.timeScale只有0和1两种情况,当Time.timeScale==1时维护realFrame=realFrame+1,这样就可以使帧数受Time.timeScale影响了。
然后计算出second时间内的运行帧数frame ,当realFrame%frame ==0时返回true。
void Update(){
if (Helper.DealInterval(.2f))
{
}
}
Helper:
/// <summary>
/// 每隔second秒时间执行1次(大致意思、不精确):返回true
/// 需要精确的需要用协程
/// </summary>
/// <param name="second"></param>
/// <returns></returns>
public static bool DealInterval(float second)
{
int frame = Mathf.RoundToInt(Application.targetFrameRate * second);
if (frame < 1) frame = 1;
return GameManager.realFrame % frame == 0;
}
GameManager:
void Update()
{
if(Time.timeScale == 1)
{
realFrame++;
}
}