内容将会持续更新,有错误的地方欢迎指正,谢谢!
拥有更好的学习体验 —— 不断努力,不断进步,不断探索 |
助力快速掌握 Unity 生命周期函数 为初学者节省宝贵的学习时间,避免困惑! |
深入探索Unity游戏开发中的生命周期函数(一)
深入探索Unity游戏开发中的生命周期函数(二)
深入探索Unity游戏开发中的生命周期函数(三)
深入探索Unity游戏开发中的生命周期函数(四)
前言:
在Unity中,生命周期函数是一系列特定的方法,它们在游戏对象或脚本实例的不同生命周期阶段被自动调用。这些函数允许开发人员在不同的时间点插入自己的代码,以便在游戏运行过程中执行特定的操作。Unity生命周期函数控制了游戏对象和脚本实例在不同阶段的行为,从而让开发人员能够管理游戏逻辑、状态和资源。
TechX 教程效果:
文章目录
一、Editor
1、Reset
Reset()函数用于在编辑器模式下重置脚本实例的属性到默认值。当用户在 Inspector 面板上点击 Reset 按钮或者首次将脚本添加到游戏对象上时,Reset() 函数会被调用。它允许你在添加脚本后自动将属性设置回初始状态,以便于编辑和测试。
- 调用时机: Reset() 函数在两种情况下被调用:
- 用户点击游戏对象的 Inspector 面板上的 Reset按钮时
- 首次将脚本添加到游戏对象上时
- 编辑器模式下调用:
- Reset()函数只会在编辑器模式下被调用,不会在游戏运行时调用。它的主要作用是为了方便开发人员在编辑器中进行调试和设置。
- 初始化默认值:
- 你可以在 Reset() 函数中设置属性的默认值,以确保每次用户点击 Reset
按钮时,属性都会被重置为你指定的默认状态。
- 注意事项:
- 在 Reset() 函数中,你只应该重置属性的值,而不应该执行过于复杂的逻辑操作。这是因为 Reset()函数在编辑器中的调用是一个初始化操作,它的目标是将属性设置为默认状态,而不是执行复杂的游戏逻辑。
using UnityEngine;
public class ResetExample : MonoBehaviour
{
public Color defaultColor = Color.white;
private void Reset()
{
// 在点击 Reset 按钮时,重置属性为默认值
defaultColor = Color.white;
}
}
二、Initialization
1、Awake
Awake() 是 Unity 生命周期中的一个重要函数,它在加载脚本实例时被调用。在游戏对象初始化的过程中,Awake() 函数提供了一个初始化环境的机会,允许你在游戏开始前做一些准备工作。
- 调用时机: Awake() 函数在脚本实例加载时被调用。这意味着当脚本所挂载的游戏对象被实例化或者激活时,Awake() 函数将被调用。以下是一些Awake()函数被调用的情况:
- 在加载场景时初始化活动的GameObject的脚本实例时
- 将先前非活动的GameObject设置为活动时
- 使用Object.Instantiate创建Gameobject
- 给活动状态的GameObject添加脚本时
- 初始化操作:
- 你可以在 Awake() 函数中执行一些初始化操作,比如初始化变量、获取引用、设置初始状态等。由于 Awake() 在 Start() 之前被调用,因此你可以在这里初始化数据以供 Start() 函数使用。
- 仅调用一次:
- Awake() 函数在脚本实例的生命周期内只会被调用一次。这意味着它适合执行只需要在开始时进行一次的操作,如资源加载、初始化状态等。
- 初始化顺序:
- 在场景中,Unity 会先加载场景中的所有对象,然后依次调用每个对象的 Awake() 函数。这里需要注意的是,Awake() 函数的调用顺序在不同对象之间是不确定的,因此避免在 Awake() 函数中依赖其他对象的初始化。
- 激活与禁用:
- 当你将一个游戏对象的脚本实例从不激活状态切换到激活状态时,其 Awake() 函数将被调用。这使得你可以在对象的激活状态改变时执行特定的初始化操作。
- 不适用协程:
- Awake() 函数不应该包含任何协程(Coroutine)操作,因为协程操作需要依赖于运行中的 MonoBehaviour 对象,而 Awake() 在所有对象的初始化之前执行。
using UnityEngine;
public class ExampleScript : MonoBehaviour
{
private int initialHealth = 100;
private void Awake()
{
Debug.Log("Awake function called.");
InitializePlayer();
}
private void InitializePlayer()
{
// 初始化玩家的属性和状态
HealthSystem healthSystem = GetComponent<HealthSystem>();
healthSystem.SetHealth(initialHealth);
}
}
2、OnEnable
OnEnable() 在游戏对象或脚本实例变为可用或激活状态时被调用。在这个函数中,你可以执行一些在对象变为激活状态时需要进行的初始化操作,比如注册事件、初始化变量等。下面是关于 OnEnable() 函数的详细介绍:
- 调用时机: OnEnable() 函数在以下情况下被调用:
- 当游戏对象被实例化并激活时。
- 当场景中的游戏对象从非激活状态切换到激活状态时。
- 当脚本实例被添加到一个已激活的游戏对象上时。
- 初始化操作: OnEnable() 函数通常用于执行在对象激活时需要进行的初始化操作。这些操作可能包括:
- 注册事件监听器,以便在特定事件发生时执行相应的逻辑。
- 初始化变量、状态或引用,以确保对象处于正确的初始状态。
- 启动协程,在对象激活时开始执行某些异步任务。
- 进行资源加载或数据加载的操作。
- 与 Start() 的区别:
- OnEnable() 函数在对象每次变为激活状态时都会被调用,而 Start() 函数只会在脚本实例第一次启用时被调用。因此,如果你希望在对象每次激活时都执行一些操作,可以使用 OnEnable() 函数。
- 注意事项:
- 尽量避免在 OnEnable() 函数中执行过于耗时的操作,因为每次对象激活时都会执行该函数,可能会导致性能问题。如果需要执行耗时操作,考虑将其放在其他生命周期函数或协程中进行,以避免阻塞主线程。
using UnityEngine;
public class EnableExample : MonoBehaviour
{
private void OnEnable()
{
// 在对象激活时执行初始化操作
Debug.Log("Object is now enabled. Initializing...");
}
}
3、Start
Start()在脚本实例第一次启用时被调用。在这个函数中,你可以进行一些初始化设置,准备游戏逻辑并执行一些需要在游戏开始时立即执行的操作。下面是关于 Start() 函数的详细介绍:
- 调用时机: Start() 函数在以下情况下被调用:
- 当脚本实例第一次被添加到一个游戏对象上时。
- 当游戏对象从非激活状态切换到激活状态,且脚本实例第一次被启用时。
- 初始化操作: Start() 函数通常用于执行在游戏开始时需要进行的初始化操作。这些操作可能包括:
- 初始化玩家的初始位置、状态和属性。
- 加载游戏所需的资源,如模型、纹理、声音等。
- 设置游戏逻辑的初始条件,确保游戏开始时处于正确的状态。
- 与 Awake() 的区别:
- Awake是在所有对象初始化完成,并且加载脚本实例的时候调用,Start是在Update第一次执行前调用,并且是在所有的Awake执行完成后调用
- Awake函数的执行和脚本实例的是否启用无关,Start函数只有在脚本实例启用的时候才会调用
- Awake不能充当协程,Start可以充当携程,可以按需延迟初始化代码
- Awake和Start在整个生命周期中只会被调用一次
- Start总是在所有Awake函数执行完之后被调用
- 注意事项:
- 尽量避免在 Start() 函数中执行过于耗时的操作,因为这会阻塞游戏的启动。如果需要执行耗时操作,可以考虑将其放在后台线程或协程中进行,以避免影响游戏的加载性能。
using UnityEngine;
public class StartExample : MonoBehaviour
{
private void Start()
{
// 在游戏开始时执行初始化操作
Debug.Log("Game started. Initializing player...");
}
}
三、Physics
1、FixedUpdate
FixedUpdate() 主要用于物理更新和固定帧率的操作。在游戏中,物理模拟通常以固定的时间步长进行,这就是 FixedUpdate() 函数的调用时机。下面是关于 FixedUpdate() 函数的详细介绍:
- 调用时机:
- FixedUpdate() 函数在固定的时间间隔内被调用,时间间隔由 Unity 的物理步长决定,默认为每秒 50 次。这使得在 FixedUpdate() 中的物理模拟和更新操作在不同的硬件上保持一致的行为。
- 物理更新:
- 由于 FixedUpdate() 在固定时间间隔内被调用,它非常适合执行物理相关的操作,如移动、碰撞检测、应用力和更新刚体属性等。由于物理引擎工作在固定的时间步长内,所以在 FixedUpdate() 中进行这些操作可以确保物理行为的稳定性。
- 与 Update() 的区别:
- FixedUpdate() 与 Update() 函数的区别在于调用频率。FixedUpdate() 在物理更新时被调用,而 Update() 在每一帧都被调用。因此,如果需要进行与物理相关的操作,应当将其放在 FixedUpdate() 中,以保证稳定和一致的物理模拟。
- 注意事项:
- 尽量避免在 FixedUpdate() 中执行涉及到较多计算的操作,以免影响游戏的性能。大部分时间消耗较大的计算应当放在 Update() 或 LateUpdate() 中进行,以便在每帧都有足够的时间来完成。
using UnityEngine;
public class CharacterMovement : MonoBehaviour
{
public float moveSpeed = 5.0f;
private void FixedUpdate()
{
// 在固定时间间隔内应用角色的移动力
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(horizontalInput, 0.0f, verticalInput) * moveSpeed * Time.fixedDeltaTime;
transform.Translate(movement);
}
}
2、OnTriggerEnter
OnTriggerEnter() 用于检测游戏对象进入触发器时触发的事件。
以下是关于 OnTriggerEnter() 函数的详细介绍:
-
调用时机: 当一个游戏对象进入与触发器碰撞的区域时,OnTriggerEnter() 函数会被调用。这个函数在碰撞发生时被触发,无论两个对象是否真正相交,只要它们的碰撞体进入触发器区域,函数就会执行。
-
参数: OnTriggerEnter(Collider other) 函数接受一个 Collider 参数 other,该参数表示进入触发器区域的其他碰撞体。通过检查 other 可以确定是哪个对象进入了触发器。
-
注意事项: OnTriggerEnter() 只会在进入触发器区域的瞬间被调用一次。
using UnityEngine;
public class TriggerZone : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
Debug.Log("Player entered the trigger zone.");
// 在这里执行触发器相关的操作,比如播放声音或显示提示
}
}
}
3、 OnTriggerStay
OnTriggerStay(Collider other) 用于检测游戏对象持续停留在触发器内部时触发的事件。
以下是关于 OnTriggerStay() 函数的详细介绍:
-
调用时机: 当一个游戏对象停留在与触发器碰撞的区域内时,OnTriggerStay() 函数会在每一帧中被调用。这个函数在碰撞发生后,只要游戏对象在触发器内部停留,就会持续被调用。
-
参数: OnTriggerStay(Collider other) 函数同样接受一个 Collider 参数 other,表示持续停留在触发器内部的其他碰撞体。你可以通过检查 other 参数来判断是哪个对象在触发器内部停留。
-
注意事项: OnTriggerStay() 在对象停留在触发器内部时持续被调用,但它的频率是以帧为单位的,因此与帧率有关。
using UnityEngine;
public class TriggerZone : MonoBehaviour
{
private void OnTriggerStay(Collider other)
{
if (other.CompareTag("Player"))
{
Debug.Log("Player is staying in the trigger zone.");
// 在这里执行触发器持续停留时的操作,如检测玩家状态、触发动作等
}
}
}
4、 OnTriggerExit
OnTriggerExit(Collider other) 用于检测游戏对象离开触发器区域时触发的事件。
以下是关于 OnTriggerExit() 函数的详细介绍:
-
调用时机: 当一个游戏对象的碰撞体与触发器不再重叠时,OnTriggerExit() 函数会被调用。这意味着游戏对象在触发器区域内部停留时不会触发该函数,只有在它真正离开触发器区域时才会被调用。
-
参数: OnTriggerExit(Collider other) 函数接受一个 Collider 参数 other,表示离开触发器区域的碰撞体。你可以通过检查 other 参数来确定是哪个对象离开了触发器区域。
-
注意事项: OnTriggerExit() 只在游戏对象的碰撞体离开触发器区域时调用一次。如果游戏对象再次进入触发器区域,然后再次离开,该函数会再次被调用。
using UnityEngine;
public class TriggerZone : MonoBehaviour
{
private void OnTriggerExit(Collider other)
{
if (other.CompareTag("Player"))
{
Debug.Log("Player has exited the trigger zone.");
// 在这里执行玩家离开触发器区域时的操作,如停止动作、播放声音等
}
}
}
5、OnColissionEnter
OnCollisionEnter(Collision collision)用于检测游戏对象发生碰撞时触发的事件。当一个游戏对象的碰撞体与另一个碰撞体发生实际碰撞时,该函数将被调用。
以下是关于 OnCollisionEnter() 函数的详细介绍:
-
调用时机: 当一个游戏对象的碰撞体与另一个碰撞体发生实际碰撞时,OnCollisionEnter(Collision collision) 函数会被调用。这意味着在碰撞体相互重叠但没有实际碰撞时,函数不会被调用。
-
参数: OnCollisionEnter(Collision collision) 函数接受一个 Collision 参数 collision,表示发生碰撞的详细信息。通过检查 collision 参数,你可以获取有关碰撞的信息,如碰撞点、碰撞力等。
-
注意事项: OnCollisionEnter() 只在游戏对象的碰撞体与其他碰撞体发生实际碰撞时调用一次。如果游戏对象再次与其他碰撞体发生碰撞,该函数会再次被调用。
using UnityEngine;
public class CarCollision : MonoBehaviour
{
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Obstacle"))
{
Debug.Log("Car collided with an obstacle.");
// 在这里执行碰撞发生时的操作,如播放声音、减少健康值等
}
}
}
6、OnColissionStay
OnCollisionStay(Collision collision) 用于检测游戏对象在发生碰撞期间持续保持接触的事件。当游戏对象的碰撞体与另一个碰撞体接触并保持接触状态时,该函数将被调用。
以下是关于 OnCollisionStay() 函数的详细介绍:
-
调用时机: 当游戏对象的碰撞体与另一个碰撞体保持接触状态时,即便没有实际的物理碰撞,OnCollisionStay(Collision collision) 函数会持续地被调用。这意味着只要碰撞体继续接触,函数将持续地调用。
-
参数: OnCollisionStay(Collision collision) 函数接受一个 Collision 参数 collision,表示接触的详细信息。通过检查 collision 参数,你可以获取有关接触的信息,如接触点、接触法线等。
-
注意事项: OnCollisionStay() 在游戏对象的碰撞体与其他碰撞体保持接触状态时持续调用。这与碰撞发生的实际物理碰撞无关,只要碰撞体保持接触,函数就会持续被调用。
7、OnColissionExit
OnCollisionExit(Collision collision) 用于检测游戏对象与另一个碰撞体结束碰撞的事件。当游戏对象的碰撞体与另一个碰撞体分离时,该函数将被调用。
以下是关于 OnCollisionExit() 函数的详细介绍:
-
调用时机: 当游戏对象的碰撞体与另一个碰撞体结束碰撞,即它们之间的接触分离时,OnCollisionExit(Collision collision) 函数将被调用。这意味着碰撞体不再接触,物理接触已经分离。
-
参数: OnCollisionExit(Collision collision) 函数同样接受一个 Collision 参数 collision,表示结束碰撞的详细信息。通过检查 collision 参数,你可以获取有关碰撞结束的信息,如分离的物体、碰撞点等。
-
注意事项: OnCollisionExit() 在游戏对象的碰撞体与其他碰撞体分离时被调用。这与物理接触的分离相关,当碰撞体分离时,函数将会被调用。
using UnityEngine;
public class Hole : MonoBehaviour
{
private void OnCollisionExit(Collision collision)
{
if (collision.gameObject.CompareTag("MovingObject"))
{
Debug.Log("Object has exited the hole.");
// 在这里执行碰撞结束时的操作,如播放音效、更新游戏状态等
}
}
}
每一次跌倒都是一次成长 每一次努力都是一次进步 |
感谢您阅读本篇博客!希望这篇内容对您有所帮助。如果您有任何问题或意见,或者想要了解更多关于本主题的信息,欢迎在评论区留言与我交流。我会非常乐意与大家讨论和分享更多有趣的内容。
如果您喜欢本博客,请点赞和分享给更多的朋友,让更多人受益。同时,您也可以关注我的博客,以便及时获取最新的更新和文章。
在未来的写作中,我将继续努力,分享更多有趣、实用的内容。再次感谢大家的支持和鼓励,期待与您在下一篇博客再见!