unity生命周期简单叙述

一.Unity 中常见的生命周期方法

1Awake(),2OnEnable(), 3Start(), 4FixedUpdate(), 5Update(), 6LateUpdate(), 7OnGUI(), 8OnDisable(), 9OnDestroy().

二.通常的执行顺序

特殊一点的方法Reset()

Reset 方法是在编辑器中调用的,并且仅在以下情况下执行:

  1. 脚本组件被添加到 GameObject 上: 当你将一个脚本组件添加到一个 GameObject 上时,如果该脚本包含 Reset 方法,该方法会在组件添加后立即被调用。

  2. 编辑器中修改了脚本的公共字段或属性: 如果在 Inspector 中修改了脚本的公共字段或属性,Reset 方法会在你停止编辑器播放或重新加载场景时调用。

  3. 重置组件: 在 Inspector 中,右键点击脚本组件的标题栏,选择 "Reset" 选项,可以手动触发 Reset 方法。

这样设计的目的是确保在编辑器中对脚本属性的修改能够及时地反映到场景中,同时提供了一个机会来确保编辑器中的属性值与脚本的初始状态保持一致。Reset 方法对于在编辑器中进行调试、初始化和同步属性状态等方面非常有用。在运行时(在构建后的实际游戏中),Reset 方法不会被调用。

构造函数甚至在脚本编辑完游戏没有启动就会调用。

1.Awake():

        在所有的游戏对象被实例化之后调用,必须在一个被激活的对象中第一次添加脚本时会调用一次Awake(),或者在未激活的对象中添加脚本后,再进行激活对象后会调用一次Awake().(即使脚本组件未被激活也会执行)

2.OnEnable():

        如果对象被启用(enabled),接着调用 OnEnable。这是对象变为激活状态时的第一个方法。

3.Start():

        方法调用时机:在对象第一次更新时调用。用于初始化,但是在 Awake 后调用。

4.FixedUpdate() 和 Update():

        在 Start 方法执行完毕后,按照固定的时间间隔调用 FixedUpdate 方法,然后在每一帧调用 Update 方法。

5.LateUpdate():

        在 Update 方法执行完毕后,调用 LateUpdate 方法。通常用于相机跟随等操作,确保在所有 Update 方法执行完毕后执行。

6.OnGUI():

        在 LateUpdate 方法执行完毕后,调用 OnGUI 方法。用于渲染 GUI 元素。

7.OnDisable():

        如果对象被禁用,调用 OnDisable 方法。在对象被禁用时执行一些清理工作。

8.OnDestroy():

        如果对象被销毁,最后调用 OnDestroy 方法。在对象销毁时执行最终的清理工作。

三.一些使用建议

1.在使用awake和start时:

1.在生命周期中都只调用一次

2.awake在start之前调用,并且在所有游戏对象的awake方法都调用完才能调用某一个游戏对象的start方法,所以如果start方法中有需要提前获取才能运行的需求,一定要写在awake中,以免报错。

3.避免在 AwakeStart 中执行过于耗时的操作,以免影响游戏启动性能。这两个方法应该用于轻量级的初始化工作。

4.脚本的构造函数一般先于Awake 和Start,但在unity中一般不直接使用构造函数。

5.Awake即使在脚本组件未被启用时也会执行,而Start必须在脚本组件被启用后才能进行执行。

 

2.UpdateFixedUpdateLateUpdate的区别

  1. Update:
    • 调用频率: 在每一帧都会调用。
    • 用途: 用于处理与游戏逻辑和用户输入相关的代码。
    • 建议用法: 处理输入、游戏逻辑、玩家控制等。
  2. FixedUpdate:
    • 调用频率: 固定的时间间隔内调用,通常默认为每秒 50 次。
    • 用途: 用于处理物理计算和更新,确保在不同平台上物理模拟的结果一致。
    • 建议用法: 处理刚体运动、物理碰撞等。
  3. LateUpdate:
    • 调用频率: 在所有 UpdateFixedUpdate 方法执行完毕后调用。
    • 用途: 用于处理相机跟随逻辑,确保在所有对象的位置和旋转更新后再执行。
    • 建议用法: 处理相机跟随、后处理效果等。

建议使用:

  • 尽量将用户输入和游戏逻辑放在 Update 中,因为它在每一帧都被调用,适合处理实时性较高的操作。
  • 将物理相关的计算放在 FixedUpdate 中,确保在固定时间间隔内进行物理更新,使得物理模拟更加准确。
  • 使用 LateUpdate 处理相机跟随逻辑,确保在所有对象的位置和旋转更新后再执行,避免相机跟随的抖动或不稳定情况。

3.onEnable和ondisable的区别

  1. OnEnable
    • 调用时机: 在对象变为激活状态(enabled)时调用,无论是在场景开始运行时还是在脚本实例化时。
    • 用途: 通常用于初始化工作、资源加载、订阅事件或启动协程等操作,确保在对象激活时执行。
    • 注意事项: 不要在 OnEnable 中执行耗时的操作,因为它可能会影响游戏的启动性能。
  2. OnDisable
    • 调用时机: 在对象变为非激活状态(disabled)时调用,例如对象被禁用或销毁。
    • 用途: 通常用于清理工作、取消订阅事件、停止协程等,确保在对象禁用或销毁时执行。
    • 注意事项: 不要在 OnDisable 中执行需要对象处于激活状态的操作。

建议使用:

  • OnEnable 中进行资源加载、初始化、订阅事件等操作,确保在对象激活时执行。
  • OnDisable 中进行清理工作、取消订阅事件、停止协程等,确保在对象禁用或销毁时执行。
  • 避免在 OnEnableOnDisable 中执行过多耗时的操作,以免影响游戏性能。

综合使用 OnEnableOnDisable 方法,可以在对象的生命周期中实现一些必要的初始化和清理逻辑,确保对象在激活和禁用时能够执行特定的操作。

四.面试可能会问的问题

1.生命周期方法的执行顺序是什么?

Awake, OnEnable, Start, FixedUpdate, Update, LateUpdate, OnGUI, OnDisable, OnDestroy.

2.为什么有时候使用 Awake 而不是 Start

Awake 在对象被实例化时调用,通常用于初始化,而 StartAwake 后执行,适合进行一次性的初始化工作。如果需要确保在所有脚本的 Awake 阶段执行,可以使用 Awake

3.LateUpdate 适用于什么样的情况?

LateUpdate 适合处理相机跟随逻辑,确保在所有对象的位置和旋转更新后再执行,避免相机抖动或不稳定情况。

4.如何处理对象被禁用和销毁时的清理工作?

OnDisable 用于在对象被禁用时执行清理操作,OnDestroy 用于在对象被销毁时执行最终的清理工作。

5.为什么不在 Update 中进行物理计算?

FixedUpdate 适合处理物理计算,因为它以固定的时间间隔调用,确保在不同平台上物理模拟的结果一致。

6.如何在编辑器中执行初始化操作?

Reset 方法中执行初始化操作,以确保在编辑器中对脚本属性的修改能够及时地反映到场景中。

7.协程能在哪些生命周期方法中使用?

协程通常在 Start 或之后的生命周期方法中使用,不建议在 Awake 中使用。

8.生命周期方法执行的频率和如何优化性能?

生命周期方法的执行频率取决于引擎调用的频率。避免在这些方法中执行过多的计算,可以提高性能。

9.如何处理单例模式在 Unity 生命周期中的问题?

使用 Awake 方法来确保单例模式在对象实例化时初始化,并使用 OnDestroy 方法来处理对象销毁时的清理工作。

例子

public class GameManager : MonoBehaviour
{
    // 单例模式实例
    private static GameManager instance;

    // 获取单例实例的方法
    public static GameManager Instance
    {
        get
        {
            if (instance == null)
            {
                // 如果实例不存在,则尝试在场景中找到已有的实例
                instance = FindObjectOfType<GameManager>();

                // 如果场景中不存在实例,则创建一个新的实例
                if (instance == null)
                {
                    GameObject obj = new GameObject("GameManager");
                    instance = obj.AddComponent<GameManager>();
                }
            }

            return instance;
        }
    }

    // 在 Awake 中确保单例的正确性
    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject); // 防止在场景切换时被销毁
        }
        else
        {
            Destroy(gameObject); // 如果有重复的实例,销毁新创建的实例
        }
    }

    // 游戏初始化逻辑
    private void Start()
    {
        // 这里可以添加游戏初始化的逻辑
    }

    // 游戏结束时的清理工作
    private void OnDestroy()
    {
        // 这里可以添加游戏结束时的清理工作
    }
}

10.MonoBehaviour 的生命周期方法和非 MonoBehaviour 类的区别是什么?

MonoBehaviour 类的生命周期方法由引擎调用,用于管理对象的生命周期,而非 MonoBehaviour 类则没有这些特殊的生命周期方法。在非 MonoBehaviour 类中,需要手动管理对象的初始化和清理。

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在下小张!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值