2.4 常用函数


文档摘要

2.4 常用函数 (Start, Update, FixedUpdate, LateUpdate, Awake, OnEnable, OnDisable, OnDestroy) 二、C# 脚本编程父章节领域 - 2.4 常用函数 (Start, Update, FixedUpdate, LateUpdate, Awake, OnEnable, OnDisable, OnDestroy) 章节详解 在 Unity 3D 游戏开发中,C# 脚本扮演着至关重要的角色。它不仅是连接游戏对象行为与游戏逻辑的桥梁,更是实现游戏机制、交互以及各种动态效果的核心工具。为了高效地控制游戏对象的生命周期和行为,Unity 提供了一系列内置的常用函数,这些函数构成了脚本执行的基础框架。

2.4 常用函数 (Start, Update, FixedUpdate, LateUpdate, Awake, OnEnable, OnDisable, OnDestroy)

二、C# 脚本编程父章节领域 - 2.4 常用函数 (Start, Update, FixedUpdate, LateUpdate, Awake, OnEnable, OnDisable, OnDestroy) 章节详解

在 Unity 3D 游戏开发中,C# 脚本扮演着至关重要的角色。它不仅是连接游戏对象行为与游戏逻辑的桥梁,更是实现游戏机制、交互以及各种动态效果的核心工具。为了高效地控制游戏对象的生命周期和行为,Unity 提供了一系列内置的常用函数,这些函数构成了脚本执行的基础框架。理解并熟练运用这些函数,是成为一名合格 Unity 开发者的必备技能。

2.4.1 Awake

详解:

Awake 函数是 Unity 中脚本生命周期中最早被调用的函数之一。它在脚本实例被创建后,立即执行,并且只执行一次。无论脚本是否启用,Awake 都会被调用。Awake 的主要目的是进行脚本的初始化设置,例如:

  • 获取组件引用:Awake 中获取其他组件的引用 (例如 GetComponent) 是一个常见的做法,因为可以确保在后续的生命周期函数中使用这些组件之前,引用已经正确初始化。

  • 初始化变量: 设置脚本内部的变量初始值,例如计数器、状态标志等。

  • 单例模式的实现: Awake 是实现单例模式的理想位置,因为它可以确保在场景加载时,单例实例被正确创建。

代码实践:

using UnityEngine; public class AwakeExample : MonoBehaviour { private Rigidbody rb; // 声明 Rigidbody 组件变量 void Awake() { Debug.Log("Awake is called!"); rb = GetComponent<Rigidbody>(); // 获取 Rigidbody 组件的引用 if (rb == null) { Debug.LogError("Rigidbody component not found!"); } else { Debug.Log("Rigidbody component found and referenced."); } // 初始化其他变量 int initialCount = 0; Debug.Log("Initial Count: " + initialCount); } void Start() { Debug.Log("Start is called after Awake."); if (rb != null) { rb.mass = 2f; // 在 Start 中可以进一步配置组件属性 Debug.Log("Rigidbody Mass set to: " + rb.mass); } } }

代码解释:

  • Awake 函数中,我们首先打印一条日志,表明 Awake 函数已被调用。

  • 接着,使用 GetComponent<Rigidbody>() 获取当前 GameObject 上的 Rigidbody 组件的引用,并将其赋值给 rb 变量。

  • 我们进行空引用检查,确保成功获取了 Rigidbody 组件。如果未找到,则输出错误日志。

  • 最后,初始化一个整数变量 initialCount 并输出其值。

  • Start 函数中,我们打印日志表明 StartAwake 之后被调用,并进一步设置了 Rigidbody 组件的 mass 属性。

Mermaid Graph TD:

图表解释:

  • 当 GameObject 出现在场景中时 (A),Unity 会检测到附加的脚本。

  • 脚本实例被创建 (C),紧接着 Awake 函数被调用 (B)。

  • Awake 函数执行脚本的初始化逻辑 (D)。

  • 初始化完成后,脚本进入就绪状态 (E)。

  • 如果脚本或 GameObject 处于启用状态,则会调用 OnEnable 函数 (F),随后调用 Start 函数 (G)。

2.4.2 OnEnable

详解:

OnEnable 函数在脚本或其所属的 GameObject 变为启用状态时被调用。这可能发生在以下几种情况:

  • 脚本刚被创建并启用时: 如果脚本被添加到 GameObject 且默认启用,OnEnable 会在 Awake 之后立即调用。

  • 脚本或 GameObject 从禁用状态变为启用状态时: 可以通过代码 (gameObject.SetActive(true), enabled = true) 或 Inspector 界面手动启用脚本或 GameObject。

  • 场景加载时,如果脚本或 GameObject 默认启用: 在场景加载过程中,所有默认启用的脚本和 GameObject 的 OnEnable 函数都会被调用。

OnEnable 的主要用途是处理启用状态下的逻辑,例如:

  • 注册事件监听器: 在启用状态下,脚本可能需要监听某些事件 (例如按钮点击事件、自定义事件等),可以在 OnEnable 中注册这些事件的监听器。

  • 初始化启用状态下的组件或变量: 某些组件或变量的初始化可能依赖于脚本的启用状态,可以在 OnEnable 中进行初始化。

  • 启动协程或动画: 在脚本启用时,可以启动一些协程或动画来开始执行特定的行为。

代码实践:

using UnityEngine; public class OnEnableExample : MonoBehaviour { private bool isEnabled = false; void OnEnable() { Debug.Log("OnEnable is called!"); isEnabled = true; // 设置启用状态标志 Debug.Log("Script is now enabled: " + isEnabled); // 注册事件监听器 (假设有一个自定义事件管理器) //EventManager.Instance.OnGameStart += OnGameStartHandler; } void OnDisable() { Debug.Log("OnDisable is called!"); isEnabled = false; // 清除启用状态标志 Debug.Log("Script is now disabled: " + isEnabled); // 取消注册事件监听器 //EventManager.Instance.OnGameStart -= OnGameStartHandler; } // 事件处理函数示例 //void OnGameStartHandler() //{ // Debug.Log("Game Start Event Received!"); //} void Update() { if (isEnabled) { // 执行启用状态下的逻辑 Debug.Log("Script is active and running Update logic."); } } }

代码解释:

  • OnEnable 函数中,我们打印日志并设置 isEnabled 变量为 true,表示脚本已启用。

  • 注释部分展示了如何注册事件监听器,例如监听一个名为 OnGameStart 的自定义事件。

  • OnDisable 函数与 OnEnable 相反,在脚本禁用时被调用,用于清除启用状态标志和取消注册事件监听器。

  • Update 函数中,我们检查 isEnabled 标志,只有在脚本启用时才执行相应的逻辑。

Mermaid Graph TD:

图表解释:

  • 当脚本或 GameObject 处于禁用状态 (A) 时,如果被启用 (B),OnEnable 函数会被调用 (C)。

  • OnEnable 函数执行启用状态下的逻辑 (D),例如注册事件监听器、初始化变量等。

  • 启用逻辑执行完成后,脚本进入启用状态 (E),并开始执行 Update 函数 (F) (如果脚本中存在 Update 函数)。

2.4.3 Start

详解:

Start 函数在脚本的生命周期中紧随 AwakeOnEnable 之后被调用。它在第一个帧更新之前执行,并且只执行一次Start 函数只有在脚本启用的情况下才会被调用。如果脚本在创建时未启用,即使后来被启用,Start 函数也只会在第一次启用时执行一次。

Start 函数通常用于执行以下操作:

  • 依赖于其他脚本的初始化: 由于 StartAwakeOnEnable 之后执行,可以确保其他脚本的 AwakeOnEnable 已经完成,因此可以在 Start 中安全地访问和依赖其他脚本的初始化结果。

  • 更复杂的初始化逻辑: 相对于 Awake 的基础初始化,Start 可以处理更复杂的初始化逻辑,例如加载配置文件、连接网络服务等。

  • 设置初始状态,例如位置、旋转、速度等:Start 中可以设置游戏对象的初始位置、旋转、速度等,确保游戏开始时对象处于正确的状态。

代码实践:

using UnityEngine; public class StartExample : MonoBehaviour { public GameObject otherGameObject; // 公开变量,可在 Inspector 中赋值 void Awake() { Debug.Log("Awake in StartExample"); } void OnEnable() { Debug.Log("OnEnable in StartExample"); } void Start() { Debug.Log("Start is called!"); if (otherGameObject != null) { Debug.Log("Other GameObject found: " + otherGameObject.name); // 可以访问 otherGameObject 的组件或属性 Transform otherTransform = otherGameObject.GetComponent<Transform>(); if (otherTransform != null) { Debug.Log("Other GameObject's position: " + otherTransform.position); } } else { Debug.LogWarning("Other GameObject is not assigned in Inspector."); } // 设置初始位置 transform.position = new Vector3(1f, 0f, 0f); Debug.Log("Initial position set to: " + transform.position); } void Update() { // 帧更新逻辑 } }

代码解释:

  • Start 函数中,我们首先打印日志表明 Start 函数已被调用。

  • 我们检查 otherGameObject 是否在 Inspector 中被赋值。如果已赋值,则输出其名称,并尝试获取其 Transform 组件并输出其位置。

  • 如果 otherGameObject 未赋值,则输出警告日志。

  • 最后,设置当前 GameObject 的初始位置为 (1, 0, 0) 并输出。

  • AwakeOnEnable 函数也添加了日志,用于观察函数调用顺序。

Mermaid Graph TD:

图表解释:

  • Awake 函数首先被调用 (A),然后是 OnEnable 函数 (B)。

  • 紧接着,Start 函数被调用 (C)。

  • Start 函数执行更复杂的初始化逻辑 (D)。

  • 初始化完成后,Unity 开始第一个帧更新 (E),并调用 Update 函数 (F) 进行第一帧的更新。

2.4.4 Update

详解:

Update 函数是 Unity 中最核心的生命周期函数之一。它在每一帧渲染之前被调用,并且会持续执行,直到脚本被禁用或 GameObject 被销毁。 Update 函数的调用频率取决于游戏的帧率 (FPS)。帧率越高,Update 函数的调用次数就越多,反之亦然。

Update 函数是处理帧级别逻辑的主要场所,例如:

  • 输入处理: 检测用户输入 (键盘、鼠标、触摸等),并根据输入执行相应的操作,例如移动角色、射击、UI 交互等。

  • 游戏逻辑更新: 更新游戏状态,例如角色移动、敌人 AI、碰撞检测、得分计算等。

  • 动画控制: 根据游戏状态和输入,控制动画的播放和状态切换。

  • 简单的物理模拟: 对于不需要精确物理模拟的场景,可以在 Update 中进行简单的物理计算,例如简单的碰撞检测和移动。

代码实践:

using UnityEngine; public class UpdateExample : MonoBehaviour { public float moveSpeed = 5f; void Update() { // 获取水平和垂直输入 float horizontalInput = Input.GetAxis("Horizontal"); float verticalInput = Input.GetAxis("Vertical"); // 创建移动方向向量 Vector3 movement = new Vector3(horizontalInput, 0f, verticalInput); movement = movement.normalized * moveSpeed * Time.deltaTime; // 归一化并乘以速度和时间 // 移动 GameObject transform.Translate(movement); // 简单日志输出 (仅在移动时输出) if (movement.magnitude > 0.01f) // 避免微小移动触发日志 { Debug.Log("Update: Moving GameObject - Input: (" + horizontalInput + ", " + verticalInput + "), Position: " + transform.position); } } }

代码解释:

  • Update 函数中,我们使用 Input.GetAxis("Horizontal")Input.GetAxis("Vertical") 获取水平和垂直方向的输入值。

  • 创建一个 Vector3 类型的 movement 向量,表示移动方向。

  • movement 向量归一化,并乘以 moveSpeedTime.deltaTimeTime.deltaTime 表示上一帧到当前帧的时间间隔,用于实现与帧率无关的平滑移动。

  • 使用 transform.Translate(movement) 移动 GameObject。

  • 添加简单的日志输出,仅在移动幅度大于一定值时才输出,避免频繁输出日志。

Mermaid Graph TD:

图表解释:

  • Start 函数执行后,Unity 进入帧循环。

  • 在每一帧开始时,Update 函数被调用 (B)。

  • Update 函数执行帧级别的游戏逻辑 (C),例如输入处理、游戏状态更新等。

  • 逻辑更新完成后,Unity 渲染当前帧 (D)。

  • 渲染完成后,Unity 准备下一帧,并再次调用 Update 函数 (E),循环往复。

2.4.5 FixedUpdate

详解:

FixedUpdate 函数与 Update 函数类似,也是周期性执行的函数,但它们之间存在关键的区别。FixedUpdate 函数的调用频率不依赖于帧率,而是由 Unity 的物理引擎控制。 FixedUpdate 函数的默认执行频率是每秒 50 次 (可以在 Unity 项目设置中调整)。

FixedUpdate 函数主要用于处理物理相关的逻辑,例如:

  • 物理模拟: 进行精确的物理计算,例如刚体运动、碰撞检测、力学模拟等。

  • 物理输入处理: 处理与物理相关的输入,例如施加力、扭矩等。

  • 与物理引擎交互: 与 Unity 的物理引擎进行交互,例如查询碰撞信息、修改物理材质等。

代码实践:

using UnityEngine; public class FixedUpdateExample : MonoBehaviour { public float forceMagnitude = 10f; private Rigidbody rb; void Start() { rb = GetComponent<Rigidbody>(); if (rb == null) { Debug.LogError("Rigidbody component is required for FixedUpdateExample!"); enabled = false; // 禁用脚本 return; } } void FixedUpdate() { // 获取水平和垂直输入 (与 Update 中类似) float horizontalInput = Input.GetAxis("Horizontal"); float verticalInput = Input.GetAxis("Vertical"); // 创建力向量 Vector3 force = new Vector3(horizontalInput, 0f, verticalInput); force = force.normalized * forceMagnitude; // 归一化并乘以力的大小 // 对 Rigidbody 施加力 rb.AddForce(force); // 简单日志输出 (仅在施加力时输出) if (force.magnitude > 0.01f) { Debug.Log("FixedUpdate: Applying Force - Input: (" + horizontalInput + ", " + verticalInput + "), Velocity: " + rb.velocity); } } }

代码解释:

  • Start 函数中,获取 Rigidbody 组件,并进行空引用检查。如果未找到 Rigidbody,则禁用脚本。

  • FixedUpdate 函数中,获取输入值,创建力向量,并归一化和乘以力的大小。

  • 使用 rb.AddForce(force)Rigidbody 施加力,使其在物理引擎的控制下运动。

  • 添加简单的日志输出,仅在施加力时输出。

Mermaid Graph TD:

图表解释:

  • Update 函数 (Frame n) 执行之后 (A),FixedUpdate 函数会被调用 (B)。

  • FixedUpdate 函数执行物理相关的逻辑 (C)。

  • Unity 执行一个物理模拟步进 (D),更新物理世界的状态。

  • Unity 检查是否需要渲染下一帧 (E)。

  • 如果需要渲染下一帧 (Yes),则渲染当前帧 (F),并进入下一帧的 Update 函数 (I)。

  • 如果不需要立即渲染下一帧 (No),例如物理模拟步进频率高于帧率,则会再次调用 FixedUpdate 函数 (G),继续进行物理模拟,直到达到渲染下一帧的时机。

FixedUpdate 的重要性:

使用 FixedUpdate 处理物理逻辑至关重要,因为它可以确保物理模拟的时间步长一致,不受帧率波动的影响。这对于创建稳定和可预测的物理行为至关重要。如果在 Update 函数中进行物理计算,由于帧率不稳定,物理模拟可能会出现不一致和不稳定的情况。

2.4.6 LateUpdate

详解:

LateUpdate 函数在所有 Update 函数执行之后,但在渲染之前被调用。它与 Update 函数一样,也是每一帧执行一次

LateUpdate 函数的主要用途是处理需要在所有 Update 函数之后执行的逻辑,例如:

  • 相机跟随: 在角色或其他游戏对象在 Update 函数中移动之后,相机需要在 LateUpdate 中更新位置,以确保相机平滑地跟随目标对象,避免抖动或延迟。

  • 平滑跟随效果: 实现一些平滑跟随效果,例如平滑的相机旋转、平滑的武器瞄准等,可以在 LateUpdate 中进行平滑处理,以减少延迟感。

  • 后处理效果: 某些后处理效果可能需要在所有游戏对象的渲染位置都确定之后才能进行,可以在 LateUpdate 中应用这些后处理效果。

代码实践:

using UnityEngine; public class LateUpdateExample : MonoBehaviour { public Transform targetTransform; // 要跟随的目标 Transform public float smoothSpeed = 5f; private Vector3 offset; // 相机与目标的初始偏移量 void Start() { if (targetTransform == null) { Debug.LogError("Target Transform is not assigned for LateUpdateExample!"); enabled = false; return; } offset = transform.position - targetTransform.position; // 计算初始偏移量 } void LateUpdate() { if (targetTransform != null) { Vector3 desiredPosition = targetTransform.position + offset; // 目标位置加上偏移量 Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed * Time.deltaTime); // 平滑插值 transform.position = smoothedPosition; // 更新相机位置 // 简单日志输出 (仅在相机位置更新时输出) if (Vector3.Distance(transform.position, desiredPosition) > 0.01f) { Debug.Log("LateUpdate: Updating Camera Position - Target Position: " + targetTransform.position + ", Camera Position: " + transform.position); } } } void Update() { // 其他对象的 Update 逻辑 (例如目标对象的移动) } }

代码解释:

  • Start 函数中,获取目标 Transform,并计算相机与目标的初始偏移量。

  • LateUpdate 函数中,计算目标位置加上偏移量,得到期望的相机位置 desiredPosition

  • 使用 Vector3.Lerp 函数在当前相机位置 transform.positiondesiredPosition 之间进行平滑插值,得到 smoothedPosition

  • smoothedPosition 赋值给 transform.position,更新相机位置,实现平滑跟随效果。

  • Update 函数中可以放置其他对象的更新逻辑,例如目标对象的移动,确保相机在目标对象移动之后再进行位置更新。

Mermaid Graph TD:

图表解释:

  • 在所有脚本的 Update 函数都执行完毕之后 (A),LateUpdate 函数会被调用 (B)。

  • LateUpdate 函数执行需要在所有 Update 之后进行的逻辑 (C),例如相机跟随、后处理效果等。

  • 逻辑执行完成后,Unity 渲染当前帧 (D)。

  • 渲染完成后,进入下一帧循环 (E)。

LateUpdate 的优势:

使用 LateUpdate 处理相机跟随等逻辑可以确保相机的位置更新发生在所有游戏对象的位置更新之后,从而避免相机抖动或延迟,提供更平滑的游戏体验。

2.4.7 OnDisable

详解:

OnDisable 函数在脚本或其所属的 GameObject 变为禁用状态时被调用。这可能发生在以下几种情况:

  • 脚本或 GameObject 被手动禁用时: 可以通过代码 (gameObject.SetActive(false), enabled = false) 或 Inspector 界面手动禁用脚本或 GameObject。

  • 场景卸载时,如果脚本或 GameObject 仍在场景中: 在场景卸载时,所有仍在场景中的脚本和 GameObject 的 OnDisable 函数都会被调用。

  • 编辑器模式下,脚本被重新编译时: 在 Unity 编辑器模式下,如果脚本被重新编译,OnDisable 函数会被调用。

OnDisable 的主要用途是处理禁用状态下的清理工作,例如:

  • 取消注册事件监听器:OnEnable 相对应,在 OnDisable 中需要取消注册在 OnEnable 中注册的事件监听器,避免内存泄漏或错误调用。

  • 停止协程或动画: 在脚本禁用时,可以停止正在运行的协程或动画,释放资源。

  • 保存临时数据: 在脚本禁用前,可以将一些临时数据保存到本地或内存中,以便下次启用时恢复状态。

代码实践:

using UnityEngine; public class OnDisableExample : MonoBehaviour { private bool isEnabled = true; void OnEnable() { Debug.Log("OnEnable in OnDisableExample"); isEnabled = true; //EventManager.Instance.OnGamePause += OnGamePauseHandler; // 假设注册事件监听器 } void OnDisable() { Debug.Log("OnDisable is called!"); isEnabled = false; //EventManager.Instance.OnGamePause -= OnGamePauseHandler; // 取消注册事件监听器 Debug.Log("Script is now disabled: " + isEnabled); // 停止协程示例 //StopCoroutine("MyCoroutine"); } // 事件处理函数示例 //void OnGamePauseHandler() //{ // Debug.Log("Game Pause Event Received!"); //} // 协程示例 //IEnumerator MyCoroutine() //{ // while (true) // { // Debug.Log("Coroutine is running..."); // yield return new WaitForSeconds(1f); // } //} void Start() { Debug.Log("Start in OnDisableExample"); //StartCoroutine("MyCoroutine"); // 启动协程示例 } }

代码解释:

  • OnDisable 函数中,我们打印日志,设置 isEnabled 变量为 false,表示脚本已禁用。

  • 注释部分展示了如何取消注册事件监听器,例如取消注册 OnGamePause 事件。

  • 另一个注释部分展示了如何停止协程,例如停止名为 "MyCoroutine" 的协程。

  • OnEnableStart 函数中添加了日志和示例代码,用于观察函数调用顺序和演示协程的启动与停止。

Mermaid Graph TD:

图表解释:

  • 当脚本或 GameObject 处于启用状态 (A) 时,如果被禁用 (B),OnDisable 函数会被调用 (C)。

  • OnDisable 函数执行禁用状态下的清理逻辑 (D),例如取消注册事件监听器、停止协程等。

  • 清理逻辑执行完成后,脚本进入禁用状态 (E)。

2.4.8 OnDestroy

详解:

OnDestroy 函数在 GameObject 被销毁时被调用。这通常发生在以下几种情况:

  • 场景卸载时: 当场景被卸载时,场景中的所有 GameObject 都会被销毁,并调用它们的 OnDestroy 函数。

  • 通过代码手动销毁 GameObject: 可以使用 Destroy(gameObject) 函数手动销毁 GameObject,此时会调用其 OnDestroy 函数。

  • 编辑器模式下,进入或退出 Play Mode 时: 在 Unity 编辑器模式下,当进入或退出 Play Mode 时,场景会被重新加载,旧场景中的 GameObject 会被销毁,并调用它们的 OnDestroy 函数。

OnDestroy 函数是脚本生命周期中最后一个被调用的函数 (除了 OnApplicationQuit,但 OnApplicationQuit 不保证在所有情况下都调用)。OnDestroy 的主要用途是进行最后的资源清理和释放,例如:

  • 释放资源: 释放脚本占用的资源,例如纹理、网格、音频剪辑等,避免内存泄漏。

  • 取消订阅静态事件: 如果脚本订阅了静态事件,需要在 OnDestroy 中取消订阅,避免在 GameObject 销毁后仍然接收到事件,导致错误。

  • 保存最终数据: 在 GameObject 销毁前,可以将一些最终数据保存到持久化存储中,例如游戏进度、玩家设置等。

代码实践:

using UnityEngine; public class OnDestroyExample : MonoBehaviour { private static int instanceCount = 0; // 静态变量,跟踪实例数量 void Awake() { instanceCount++; Debug.Log("Awake in OnDestroyExample - Instance Count: " + instanceCount); } void OnDestroy() { instanceCount--; Debug.Log("OnDestroy is called! - Instance Count: " + instanceCount); // 释放资源示例 (假设脚本加载了纹理) //Texture2D myTexture = GetComponent<Renderer>().material.mainTexture as Texture2D; //if (myTexture != null) //{ // Destroy(myTexture); // 释放纹理资源 //} } void Start() { Debug.Log("Start in OnDestroyExample"); } }

代码解释:

  • Awake 函数中,我们递增静态变量 instanceCount,用于跟踪 OnDestroyExample 脚本的实例数量。

  • OnDestroy 函数中,我们递减 instanceCount,并打印日志,显示 OnDestroy 函数已被调用以及当前的实例数量。

  • 注释部分展示了如何释放纹理资源,例如释放附加到 Renderer 组件的纹理。

  • Start 函数中添加了日志,用于观察函数调用顺序。

Mermaid Graph TD:

图表解释:

  • 当场景中存在 GameObject (A) 时,如果该 GameObject 被销毁 (B),OnDestroy 函数会被调用 (C)。

  • OnDestroy 函数执行最后的清理逻辑 (D),例如释放资源、取消订阅静态事件等。

  • 清理逻辑执行完成后,GameObject 被彻底销毁 (E)。

OnDestroy 的重要性:

OnDestroy 函数是确保资源得到正确释放和清理的最后机会。在 OnDestroy 中进行必要的清理工作,可以避免内存泄漏、资源浪费等问题,提高游戏的性能和稳定性。

总结

理解并熟练运用 Unity C# 脚本的常用生命周期函数 (Awake, OnEnable, Start, Update, FixedUpdate, LateUpdate, OnDisable, OnDestroy) 是 Unity 开发的基础和关键。每个函数都有其特定的用途和执行时机,合理地利用这些函数,可以有效地组织和管理游戏逻辑,实现高效、稳定、可维护的游戏代码。

  • Awake: 用于脚本实例创建后的立即初始化,例如获取组件引用、初始化变量。

  • OnEnable: 用于处理脚本或 GameObject 启用时的逻辑,例如注册事件监听器。

  • Start: 用于第一个帧更新前的初始化,可以依赖其他脚本的初始化结果,处理更复杂的初始化逻辑。

  • Update: 用于每一帧的逻辑更新,处理输入、游戏状态更新、动画控制等。

  • FixedUpdate: 用于物理相关的逻辑更新,确保物理模拟的时间步长一致,提高物理模拟的稳定性。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U