unity常用的生命周期函数

本文详细介绍了Unity中常用的生命週期函数,包括Reset、Awake、OnEnable、Start、FixedUpdate等,解释了它们的用途及调用时机,帮助开发者更好地理解和运用这些函数。

今天给大家总结一下我们常用的生命周期函数:

void Reset()

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

public GameObject target;
void Reset() {          
  target = GameObject.FindWithTag("Player");

}

void  Awake ()

当一个脚本实例被载入时Awake被调用。
Awake用于在游戏开始之前初始化变量或游戏状态。
在脚本整个生命周期内它仅被调用一次Awake在所有对象被初始化之后调用,所以可以安全的与其他对象对话或用诸如 GameObject.FindWithTag 这样的函数搜索它们。
每个游戏物体上的Awke以随机的顺序被调用。
Awake总是在Start之前被调用。
Awake像构造函数一样只被调用一次。

void OnEnable()

当对象变为可用或激活状态时此函数被调用。
OnEnable不能用于协同程序。
using UnityEngine;
using System.Collections;
public class OnEnabledTest : MonoBehaviour 

   void OnEnable() {  
  Debug.Log("script was enabled");
   }
}

void Start()

Start仅在Update函数第一次被调用前调用。
Start在behaviour的生命周期中只被调用一次。
它和Awake的不同是Start只在脚本实例被启用时调用。
可以按需调整延迟初始化代码。
Awake总是在Start之前执行。
允许你协调初始化顺序。
初始化目标变量, 目标是私有的并且不能在检视面板中编辑
using UnityEngine;
using System.Collections;
public class StartTest : MonoBehaviour 

   private GameObject target; 
   void Start()
   {   
       target = GameObject.FindWithTag("Player");
   }
}

void FixedUpdate()

固定更新void FixedUpdate ()处理基于物理游戏行为一般用该方法,处理Rigidbody时,需要用FixedUpdate代替Update。当MonoBehaviour启用时,其 FixedUpdate 在每一帧被调用。
例如:给刚体加一个作用力时,必须应用作用力在FixedUpdate里的固定帧,而不是Update中的帧。(两者帧长不同)每帧应用一个向上的力到刚体上
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour
{   
   void FixedUpdate() 
   {      
      rigidbody.AddForce(Vector3.up);
   }
}

void OnTriggerXXX(Collider other)

进入触发器void OnTriggerEnter (Collider other) 当Collider(碰撞体)进入trigger(触发器)时调用OnTriggerEnter。
逗留触发器void OnTriggerStay (Collider other) 当碰撞体接触触发器时,OnTriggerStay将在每一帧被调用。
退出触发器void OnTriggerExit  (Collider other)当Collider(碰撞体)停止触发trigger(触发器)时调用OnTriggerExit。

void  OnCollisionXXX (Collision collisionInfo)

进入碰撞 void  OnCollisionEnter (Collision collisionInfo),当此collider/rigidbody触发另一个rigidbody/collider时,OnCollisionEnter将会在开始碰撞时调用。
逗留碰撞 void  OnCollisionStay (Collision collisionInfo),当此collider/rigidbody触发另一个rigidbody/collider时,OnCollisionStay将会在每一帧被调用。
退出碰撞 void  OnCollisionExit (Collision collisionInfo),当此collider/rigidbody停止触发另一个rigidbody/collider时,OnCollisionExit将被调用。
Collision包含接触点,碰撞速度等细节。如果在函数中不使用碰撞信息,省略collisionInfo参数以避免不必要的运算.

void OnMouseXXX()

void OnMouseUp ():当用户释放鼠标按钮时调用OnMouseUp。OnMouseUp只调用在按下的同一物体上。此函数在iPhone上无效。
void OnMouseDown ():当鼠标在Collider(碰撞体)上点击时调OnMouseDown。
void OnMouseEnter ():当鼠标进入到Collider(碰撞体)中时调用OnMouseEnter。
void OnMouseExit ():当鼠标移出Collider(碰撞体)上时调用OnMouseExit。
void OnMouseOver ()当鼠标悬浮在Collider(碰撞体)上时调用 OnMouseOver 。
using UnityEngine;
using System.Collections;
public class OnMouseXXX : MonoBehaviour {
    void OnMouseEnter()
    {
        Debug.Log("当鼠标进入");
    }
    void OnMouseDown()
    {
        Debug.Log("当鼠标按下");
    }
   void OnMouseDrag()
    {
        Debug.Log("当鼠标拖动");
    }
    void OnMouseExit()
    {
        Debug.Log("当鼠标推出");
    }
    void OnMouseOver()
    {
        Debug.Log("当鼠标经过");
    }
}

void Update ()

当MonoBehaviour启用时,其Update在每一帧被调用。Update是实现各种游戏行为最常用的函数。
using UnityEngine;
using System.Collections;
public class UpdateTest : MonoBehaviour 
{   
   void Update() {      
      transform.Translate(0, 0, Time.deltaTime * 1);
   }
}

void LateUpdate () 

当Behaviour启用时,其LateUpdate在每一帧被调用。
LateUpdate是在所有Update函数调用后被调用。
这可用于调整脚本执行顺序。例如:当物体在Update里移动时,跟随物体的相机可以在LateUpdate里实现。

void OnGUI() 

void OnGUI() 

{

if (GUI.Button(new Rect(10, 10, 150, 100), "I am a button"))
print("You clicked the button!");
}

void OnDisable ()

当对象变为不可用或非激活状态时此函数被调用。当物体被销毁时它将被调用,并且可用于任意清理代码。脚本被卸载时,OnDisable将被调用,OnEnable在脚本被载入后调用。

void OnDestroy ()

当MonoBehaviour将被销毁时,这个函数被调用。OnDestroy只会在预先已经被激活的游戏物体上被调用

<think> 我们被要求回答关于Unity生命周期函数的问题。根据引用[1],生命周期函数Unity引擎在游戏对象或脚本的特定阶段自动调用的预定义方法,属于MonoBehaviour类,由Unity内部管理执行顺序和触发时机。引用[2]提到了Awake函数的具体调用情况、时间和作用。 根据这些信息,我们可以整理Unity生命周期函数的主要阶段和函数: 1. **初始化阶段**: - `Awake()`: 当脚本实例被加载时调用,无论脚本是否启用。通常用于初始化变量或引用[^2]。调用次数:仅一次。 - `OnEnable()`: 当对象变为启用和激活状态时调用(例如,通过`SetActive(true)`或首次创建时)。 - `Start()`: 在脚本启用后,第一次Update之前调用。用于初始化需要依赖其他对象的内容(因为此时所有对象的Awake都已执行完毕)[^1]。 2. **更新阶段**: - `FixedUpdate()`: 固定时间间隔调用,用于物理计算(与物理引擎同步)。 - `Update()`: 每帧调用一次,是游戏逻辑的主要更新点。 - `LateUpdate()`: 在所有Update函数执行完毕后调用,常用于摄像机跟随等操作。 3. **渲染阶段**(与渲染相关): - `OnWillRenderObject()`: 当对象即将被渲染时调用(每个相机一次)。 - `OnBecameVisible()`/`OnBecameInvisible()`: 当对象进入/离开相机的视锥体时调用。 4. **销毁阶段**: - `OnDisable()`: 当对象变为禁用或非激活状态时调用(例如,通过`SetActive(false)`)。 - `OnDestroy()`: 当对象被销毁时调用(例如,场景切换或`Destroy(gameObject)`后)。 5. **其他特殊回调**: - `OnTriggerEnter()`/`OnCollisionEnter()`等:物理碰撞事件。 - `OnMouseDown()`/`OnMouseOver()`等:输入事件。 注意:引用[3]提到动画的生命周期,但未直接提供新的生命周期函数,因此不纳入主要列表。 为了清晰,我们可以用表格形式展示主要生命周期函数的执行顺序和特性: | 阶段 | 函数名 | 触发条件 | 调用次数 | 典型用途 | |--------------|---------------------|--------------------------------------------------------------------------|----------|----------------------------------| | 初始化 | `Awake()` | 脚本实例化时(无论是否激活) | 一次 | 初始化变量、获取组件引用 | | | `OnEnable()` | 脚本启用时(首次激活或`SetActive(true)`后) | 多次 | 注册事件、重置状态 | | | `Start()` | 脚本启用后,第一次`Update`前 | 一次 | 依赖其他对象的初始化 | | 物理更新 | `FixedUpdate()` | 固定时间步长(默认0.02秒) | 多次 | 物理相关计算(如Rigidbody控制) | | 游戏更新 | `Update()` | 每帧一次(帧率依赖) | 多次 | 游戏逻辑、输入处理 | | | `LateUpdate()` | 所有`Update`执行完毕后 | 多次 | 摄像机跟踪、后续处理 | | 渲染回调 | `OnBecameVisible()` | 对象进入任意相机视锥体 | 多次 | 需要时才开始渲染相关操作 | | | `OnBecameInvisible()`| 对象离开所有相机视锥体 | 多次 | 节省资源(如停止粒子效果) | | 禁用/销毁 | `OnDisable()` | 脚本禁用时(`SetActive(false)`或销毁前) | 多次 | 清理临时数据、取消事件注册 | | | `OnDestroy()` | 对象销毁前(场景切换或`Destroy()`调用后) | 一次 | 释放资源、持久化数据 | > 📌 **关键顺序**:`Awake` → `OnEnable` → `Start` → `FixedUpdate`/`Update`/`LateUpdate` → `OnDisable` → `OnDestroy`[^1][^2] ### 注意事项: 1. **执行顺序问题**:不同脚本的`Awake`调用顺序不确定,但同一游戏对象上的脚本按它们在Inspector中的顺序执行。 2. **激活依赖**:如果游戏对象初始为未激活状态,则`Awake`会在首次激活时调用(但`Start`仍等到首次激活后的更新前)[^2]。 3. **多场景切换**:使用`DontDestroyOnLoad`的对象在场景切换时不会触发`OnDestroy`,直到游戏退出。 最后,生成相关问题: §§相关问题§§ 1. Unity生命周期函数的精确执行顺序是怎样的? 2. 如何控制同一游戏对象上多个脚本的生命周期执行顺序? 3. OnEnable和Start的区别是什么?分别在什么场景下使用? 4. Unity事件函数(如碰撞检测)属于生命周期函数吗?它们何时执行? </think> ### Unity生命周期函数详解 Unity生命周期函数是`MonoBehaviour`脚本中由引擎自动调用的特殊方法,它们在游戏对象的特定阶段触发,用于控制初始化、更新和销毁过程。以下是主要生命周期函数及其执行顺序: #### **一、核心生命周期函数** | 阶段 | 函数名 | 触发时机 | 调用次数 | 典型用途 | |--------------|---------------------|--------------------------------------------------------------------------|----------|----------------------------------| | **初始化** | `Awake()` | 脚本实例化时(无论脚本是否启用) | 一次 | 初始化变量、获取组件引用[^2] | | | `OnEnable()` | 脚本启用时(首次激活或`SetActive(true)`后) | 多次 | 注册事件、重置状态 | | | `Start()` | 脚本启用后,第一次`Update`前 | 一次 | 依赖其他对象的初始化 | | **更新循环** | `FixedUpdate()` | 固定时间步长(默认0.02秒) | 多次 | 物理相关计算(如Rigidbody控制) | | | `Update()` | 每帧一次(帧率依赖) | 多次 | 游戏逻辑、输入处理 | | | `LateUpdate()` | 所有`Update`执行完毕后 | 多次 | 摄像机跟踪、后续处理 | | **渲染** | `OnPreRender()` | 相机开始渲染场景前 | 多次 | 自定义渲染预处理 | | | `OnPostRender()` | 相机完成场景渲染后 | 多次 | 后期处理效果 | | **销毁** | `OnDisable()` | 脚本禁用时(`SetActive(false)`或销毁前) | 多次 | 清理临时数据、取消事件注册[^1] | | | `OnDestroy()` | 对象销毁前(场景切换或`Destroy()`调用后) | 一次 | 释放资源、持久化数据 | #### **二、特殊场景函数** 1. **物理碰撞检测** - `OnCollisionEnter()`:碰撞开始时触发 - `OnTriggerExit()`:触发器退出时触发 2. **鼠标交互** - `OnMouseDown()`:鼠标点击对象时 - `OnMouseOver()`:鼠标悬停时 3. **激活状态变化** - `OnBecameVisible()`:对象进入相机视锥体 - `OnBecameInvisible()`:对象离开相机视锥体 #### **三、执行顺序图示** ```mermaid graph LR A[Awake] --> B[OnEnable] B --> C[Start] C --> D[FixedUpdate] D --> E[Update] E --> F[LateUpdate] F --> G[OnPreRender] G --> H[OnPostRender] H --> I[OnDisable] I --> J[OnDestroy] ``` > 📌 **关键规则**: > 1. `Awake` 总是优先执行,即使脚本未激活[^2] > 2. `Start` 仅在脚本激活后执行一次 > 3. 禁用对象 (`SetActive(false)`) 会跳过所有更新函数,但触发 `OnDisable`[^1] > 4. 脚本执行顺序可通过 **Edit > Project Settings > Script Execution Order** 调整 #### **四、生命周期应用示例** ```csharp public class LifecycleDemo : MonoBehaviour { private Rigidbody rb; void Awake() { rb = GetComponent<Rigidbody>(); // 初始化组件引用 } void OnEnable() { Debug.Log("对象激活"); // 注册事件等 } void Start() { rb.velocity = Vector3.forward * 10; // 依赖Awake初始化的组件 } void FixedUpdate() { rb.AddForce(Vector3.down * 9.8f); // 物理模拟 } void OnDisable() { Debug.Log("对象禁用"); // 清理资源 } } ``` #### **五、常见误区** 1. ❌ 错误:在 `Awake` 中访问其他未初始化对象 ✅ 解决:改用 `Start` 确保依赖对象已初始化 2. ❌ 错误:期望 `OnDestroy` 在场景切换时立即执行 ✅ 注意:Unity会批量处理销毁,可能有延迟
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值