目录
2.Unity生命周期的主要阶段及各个阶段常用的生命周期函数
1)OnTriggerXXX(Collider other):触发检测
①void OnTriggerEnter (Collider other):
②void OnTriggerStay (Collider other):
③void OnTriggerExit(Collider other):
2)OnCollisionXXX (Collision collisionInfo):碰撞检测
①void OnCollisionEnter(Collision collisionInfo):
②void OnCollisionStay(Collision collisionInfo):
③void OnCollisionExit (Collision collisionInfo):
本篇文章学习一下Unity的生命周期,想要学好Unity,就必须先熟练掌握Unity的生命周期,才能将各种操作放在合适的阶段执行。
1.什么是生命周期
在Unity中,生命周期方法的调用涉及到游戏对象和脚本,但实际上生命周期的管理主要是基于脚本的。
1)游戏对象生命周期
游戏对象的生命周期主要有这几个状态:创建、激活、禁用和销毁。游戏对象的状态直接影响挂载在其上的脚本的生命周期和函数调用。
①创建:游戏对象被创建时,它的所有组件(包括脚本)都会被初始化,但这时脚本的生命周期方法尚未被调用。
②激活:当游戏对象被激活时,脚本的生命周期方法开始生效。如果游戏对象在场景中被激活或设置为启用状态,那么挂载在该对象上的所有脚本附加的脚本会按顺序调用OnEnable()、Start()等生命周期函数。
③禁用:当游戏对象被禁用时,游戏对象及所有挂载的脚本会停止调用生命周期函数,直到它再次被启用。
④销毁:当游戏对象被销毁时,它和所有附加的组件(包括脚本)都会被清理,相关的生命周期方法会被调用来处理清理工作。
2)脚本生命周期
只有继承了MonoBehavior的脚本才可挂载到游戏对象上,这样的脚本才有生命周期。脚本的生命周期与游戏对象的状态密切相关,但脚本的生命周期函数会按照固定顺序执行,即该脚本从创建到销毁的各个阶段,这就是我们说的Unity的生命周期。
总而言之,脚本的生命周期受依赖于游戏对象的状态影响。
2.Unity生命周期的主要阶段及各个阶段常用的生命周期函数
主要有四个阶段:初始化阶段->更新阶段->渲染阶段->销毁阶段,下面的讲述的顺序也是生命周期函数的执行顺序。
1)初始化阶段
①Awake():
在脚本实例被加载时调用,用于初始化变量或设置对象的初始状态。这是在游戏对象启用之前调用的。注意:在脚本整个生命周期内它仅被调用一次,且每个游戏物体上的Awke以随机的顺序被调用,Awake总是在Start之前被调用。
为了更好地看到效果,我们可以在之前成功的Unity项目的基础上新建一个场景 (1.初识Unity,了解一个Unity项目的完整创建流程(超详细))
using UnityEngine;
public class Test01 : MonoBehaviour
{
private void Awake()
{
//在控制台打印
Debug.Log("Awake()函数被调用!");
}
}
②OnEnable():
当脚本或对象被激活时调用,用于处理对象激活时的逻辑。同理,进行如下测试。
using UnityEngine;
public class Test01 : MonoBehaviour
{
private void OnEnable()
{
Debug.Log("OnEnable()函数被调用!");
}
}
③Start():
在所有Awake()方法调用完成后并且所有游戏对象已启用时调用,用于脚本的初始设置和游戏逻辑初始化。在第一个Update发生之前调用一次。同理,进行如下测试。
using UnityEngine;
public class Test01 : MonoBehaviour
{
private void Start()
{
Debug.Log("Start()函数被调用!");
}
}
2)更新阶段:
①FixedUpdate():
每固定时间间隔调用一次,通常是0.02s,用于处理物理计算。如处理力,给游戏对象加上刚体(Rigidbody)组件后,通过刚体给物体加一个作用力时,必须在FixedUpdate里的固定帧执行,而不是Update中的帧,两者帧长不同,每帧应用一个力到刚体上。如果没有刚体(Rigidbody)组件,对象将不会受到物理引擎的影响,也就无法参与物理模拟和力的应用,所以需要给游戏对象添加刚体,但没加刚体组件的物体可以通过碰撞检测(Collider)来触发事件。
新建一个Cube,给该Cube加上刚体组件,并挂载测试脚本。
using UnityEngine;
public class FixedUpdateTest : MonoBehaviour
{
public new Rigidbody rigidbody;
private void FixedUpdate()
{
rigidbody.AddForce(Vector3.up);
}
}
②Update():
每帧调用一次,用于常规的游戏逻辑处理,如输入检测和对象移动。同理,新建一个三维物体,挂载脚本进行测试。
using UnityEngine;
public class UpdateTest : MonoBehaviour
{
//Unity中脚本的成员访问权限不写,默认是private
void Update()
{
transform.position += new Vector3(Time.deltaTime * 1.2f, 0,0);
}
}
③LateUpdate():
在所有Update()方法之后调用,用于在所有对象更新后处理逻辑,如当物体在Update里移动时,跟随物体的相机可以在此处实现。
using UnityEngine;
public class UpdateTest : MonoBehaviour
{
//Unity中脚本的成员访问权限不写,默认是private
void Update()
{
transform.position += new Vector3(Time.deltaTime * 1.2f, 0,0);
}
private void LateUpdate()
{
Camera.main.transform.position = transform.position+ new Vector3(0, 0.7f, -1.5f);
}
}
3)渲染阶段:
OnGUI():
主要用于绘制即时用户界面元素和调试信息,适用于创建和管理GUI界面,如绘制一个按钮。该方法用于旧输入系统,而本项目使用的是新的输入系统,可以查看到。
4)销毁阶段:
①OnApplicationQuit():
当应用程序退出时调用,用于清理代码、保存数据或执行其他在退出时需要完成的操作。同理,进行如下测试。
using UnityEngine;
public class Test01 : MonoBehaviour
{
private void OnApplicationQuit()
{
Debug.Log("OnApplicationQuit()函数被调用!");
}
}
②OnDisable():
当脚本或游戏对象被禁用时调用,用于清理操作或停止处理。同理,进行如下测试。
using UnityEngine;
public class Test01 : MonoBehaviour
{
private void OnDisable()
{
Debug.Log("OnDisable()函数被调用!");
}
}
③OnDestroy():
当游戏对象被销毁时调用,用于释放资源或执行清理操作。同理,进行如下测试,将之前所有测试的生命周期函数加上,可以看到控制台打印的语句顺序,就是生命周期函数执行的顺序。
using UnityEngine;
public class Test01 : MonoBehaviour
{
private void Awake()
{
//在控制台打印
Debug.Log("Awake()函数被调用!");
}
private void OnEnable()
{
Debug.Log("OnEnable()函数被调用!");
}
private void Start()
{
Debug.Log("Start()函数被调用!");
}
private void OnApplicationQuit()
{
Debug.Log("OnApplicationQuit()函数被调用!");
}
private void OnDisable()
{
Debug.Log("OnDisable()函数被调用!");
}
private void OnDestroy()
{
Debug.Log("OnDestroy()函数被调用!");
}
}
3.其他
在更新阶段的FixedUpdate()和Update ()函数间还有如下生命周期函数会调用
1)OnTriggerXXX(Collider other):触发检测
通常一起使用。
①void OnTriggerEnter (Collider other):
进入触发器,当Collider(碰撞体)进入trigger(触发器)时调用。
②void OnTriggerStay (Collider other):
逗留触发器,当碰撞体接触触发器时,OnTriggerStay将在每一帧被调用。
③void OnTriggerExit(Collider other):
退出触发器,当Collider(碰撞体)停止触发trigger(触发器)时调用。
2)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参数以避免不必要的运算.
3)OnMouseXXX():鼠标交互
①void OnMouseEnter ():
鼠标进入,当鼠标进入到Collider(碰撞体)中时调用。
②void OnMouseDown ():
鼠标按下,当鼠标在Collider(碰撞体)上点击时调用。
③void OnMouseUp ():
鼠标弹起,当用户释放鼠标按钮时调用。OnMouseUp只调用在按下的同一物体上。此函数在iPhone上无效。
④void OnMouseExit ():
鼠标移出,当鼠标移出Collider(碰撞体)上时调用。
⑤void OnMouseOver ():
鼠标悬浮,当鼠标悬浮在Collider(碰撞体)上时调用。
可以在Unity手册进行查看https://docs.unity.cn/cn/2020.3/Manual/ExecutionOrder.html。下图是Unity手册上的脚本生命周期流程图。
好了,本次的分享到这里就结束啦,我相信你肯定有所收获,优秀,给自己点个赞叭~