找回密码
 立即注册
查看: 237|回复: 2

Unity学习路线-理论知识部分-Unity-Unity基础-Unity生命周期 ...

[复制链接]
发表于 2023-2-28 19:30 | 显示全部楼层 |阅读模式
- 个人整理翻译版本新版Unity生命周期

- 官方新版生命周期



- 个人整理翻译版本


生命周期函数

1、初始化阶段

Awake(唤醒)
当一个脚本实例被载入时Awake被调用,无论脚本是否可用,只要物体被加载就会调用,Awake常用于在游戏开始之前初始化变量或游戏状态,可以判断当满足条件后执行此脚本(只调用一次)。

OnEnable(当可用)
当对象变为可用或激活状态时此函数被调用。(可多次调用)。

Reset(重置)(Editor)
Reset是在用户点击检视面板的Reset按钮或者首次添加该组件时被调用。此函数只在编辑模式下被调用。Reset最常用于在检视面板中给定一个最常用的默认值。

Start(开始)
物体载入且脚本对象启用时被调用1次,常用于数据或逻辑对象初始化(只调用一次)。
Start仅在Update函数第一次被调用前调用,且只会在脚本实例启用时被调用一次。
Awake总是在Start之前执行。可以按需调整延迟初始化代码。

2、物理阶段

FixedUpdate(固定更新)
FixedUpdate基于一个可靠的定时器被调用,独立于帧率之外。如果固定的时间步长小于实际的帧更新时间,那么每帧的物理循环可能会发生不止一次。处理物体的物理属性(Rigidbody、Force、Collider)或者输入事件时,需要用FixedUpdate代替Update,以使物体的物理表现更平滑。实际上,FixedUpdate并不是真的按照现实时间间隔执行的,而是按照Timer时间间隔执行的,但Timer并不是真正意义上的现实时间,它的作用是在运行环境下创造一个与现实时间高度相近的变量来实现物理帧的逻辑稳定。因为FixedUpdate的这个特质,强烈建议在此环节只做物理相关的处理,不要把其他类型(如网络帧同步)的处理也放入此步骤。默认频率大概为0.02s,该频率可手动修改。

在这期间的操作
固定更新结束后,系统内部会进行一系列的操作,最重要的莫过于Unity的内部物理更新,这个是真正的物理更新操作执行。
具体执行步骤大概如下:


OnTriggerXXX(触发)
触发器被触发时调用。

OnCollisionXXX(碰撞)
产生碰撞事件时调用。

yield WaitForFixedUpdate(协程:物理帧结束)
当物理帧执行完毕后会跳转到此协程,协程的调用跟方法是不同的,可以理解为在一段代码中设置一个卡点,当程序执行到这个卡点所匹配的时机时卡点后面的代码才会继续执行。
public class Test : MonoBehaviour
{
    void Awake()
    {
        Debug.Log("0");
        StartCoroutine(TestCoroutine());
        Debug.Log("2");
    }

    void FixedUpdate()
    {
        Debug.Log("3 - FixedUpdate");
    }

    IEnumerator TestCoroutine()
    {
        Debug.Log("1");
        yield return new WaitForFixedUpdate();
        Debug.Log("4");                      // 当物理帧结束(触发WaitForFixedUpdate)后才会执行这条语句。
    }
}
物理阶段总结
该阶段的发生与渲染无关,其特性决定了其处理物理事件的功能,使物理展示效果更为平滑,另外固定更新的频率并非真的是固定的,实际的执行会根据CPU轮转时间片产生偏移,但这个偏移基本可以忽略不记。

3、输入事件阶段

鼠标、键盘、触屏、手柄等各类输入事件会在这个阶段触发,这个时间点物理更新已经执行(如果需要物理更新的话),而逻辑更新和渲染并未执行,要了解这个触发的时机,才能更好的掌握代码逻辑。

4、游戏逻辑阶段

Update(更新)
Update是真正的每帧调用的,由于系统性能以及游戏体量的区别,每一帧的刷新频率也是不同的,所以不要过分期待在Update方法中按时完成任务。
Update与FixedUpdate实际上是使用同一个线程的,update在loop中的处理方式是本次更新完毕再根据上一帧到现在的偏移时间判断是否进行下一次更新,Update的本质就是回调函数。只要是回调函数就存在上下文传递的损耗,所以如果想减少回调,可以考虑自己实现一套update机制,使用虚函数来代替update。
判断多个协程点
在yield WaitForFixedUpdate章节已经讲过协程的执行顺序,当Update执行过后,将会到达以下几个协程的触发点,如果在此之前设置了相关的协程,这时就会生效。

yield null
yield WaitForSeconds
yield WWW:这个比较重要,当网络任务执行完成后,会在当前帧的这个时间点执行WWW之后的操作。一般用于异步加载资源。
yield StartCoroutine
内部动画更新
在几个协程过后,Unity将进行第二次大规模的系统内部操作,主要的工作内容就是动画的更新,具体内容如下:


LateUpdate(延后更新)
每帧Update方法调用之后会调用本方法。因为游戏开发过程中经常会有一个二次计算的情况,比如主角移动,相机跟着移动。如果相机也在主角移动时跟随,当有物体跟玩家之间产生了相位,就可能会出现抽搐抖动等情况(因为并没有在这一帧逻辑完全结束后调用跟随)。所以LateUpdate的出现能够使程序更加顺畅。

5、渲染阶段

OnWillRenderObject
当即将渲染物体时调用。

OnPreCull
这个函数仅用于宿主为摄像机的脚本。当此摄像机剔除了某个渲染场景时候触发此消息。

OnBecameVisable(即将可见)
当物体即将可见时调用。

OnBecameInvisible(即将不可见)
当物体即将不可见时调用。
OnPreRender(即将渲染)
这个函数仅用于宿主为摄像机的脚本。当此摄像机开始渲染某个场景时候触发此消息。
在所有渲染开始之前调用,这个方法其实是很考究的,我看到大部分网友对于这个方法都是抄了几种用法:加入脚本、设定标题、设定按钮客户端事件、设定控件的状态、加入脚本块。
个人觉得渲染前可以做的事并不仅仅如此,比如是不是可以考虑在渲染前做一些渲染优化,虽然现在已经有很多插件了,但是如果程序设计的好可以考虑自己实现一套优化,这样更贴合自己的程序。

OnRenderObject
这个函数仅用于宿主为摄像机的脚本。当使用Graphics.DrawMeshNow 或者其他函数绘制自己建立的物体渲染完毕时触发。

OnPostRender
这个函数仅用于宿主为摄像机的脚本。当此摄像机范围内所有渲染都完成时候触发此消息。

OnRenderImage
当所有渲染完成image的postprocessing effects(只有pro版支持)后触发。

OnDrawGizmos(Gizmos渲染)
Gizmos一般是为开发者使用的,指的是开发时场景编辑器中所展示的那些相机、线框之类的物体。所以此方法里的内容一般不会需要发布到生产环境中。

GUI渲染
用户界面渲染的工作会在这一步执行。

yield WaitForEndOfFrame(协程:帧结束)
当前帧彻底结束后会执行此协程。协程运行情况如下:
public class Test : MonoBehaviour
{
    void Awake()
    {
        Debug.Log("0");
        StartCoroutine(TestCoroutine());
        Debug.Log("2");
    }

    void Update()
    {
        Debug.Log("3 - Update");
    }

    void LateUpdate()
    {
        Debug.Log("4 - LateUpdate");
    }

    IEnumerator TestCoroutine()
    {
        Debug.Log("1");
        yield return new WaitForEndOfFrame();
        Debug.Log("5");                      // 当帧结束(触发WaitForEndOfFrame)后才会执行这条语句。
    }
}
6、暂停阶段

OnApplicationPause(应用暂停)
应用暂停时会调用此方法,取消暂停后会从FixedUpdate开始重新执行。

7、退出阶段

OnDestroy(销毁)
当物体被销毁时调用,一般用于清理内存。

OnApplicationQuit(应用退出)
当应用退出时调用,但有时会失效,此方法为不稳定的方法,正常情况下可以用于保存退出前的信息,但最好使用更稳妥的方式,因为此方法有时不会被调用,比如Android环境。

原文链接:【Unity】Unity 生命周期

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2023-2-28 19:40 | 显示全部楼层
整理得不错~给个小建议:官方的那张图是svg格式的心可以直接在它上面写批注[抱抱]
发表于 2023-2-28 19:44 | 显示全部楼层
噢,谢谢呀,学习了~之前还真不知道这个[爱]
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-16 12:34 , Processed in 0.091289 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表