Unity默认函数执行顺序(搬运整理)
函数执行生命周期
目录
yield return new WaitForFixedUpdate
yield return new WaitForSeconds
yield return WaitForEndOfFrame
Reset() 重置
Reset是在用户点击检视面板的Reset按钮或者首次添加该组件时被调用。此函数只在编辑模式下被调用。Reset最常用于在检视面板中给定一个最常用的默认值。
public GameObject target;
void Reset()
{
if (!typeof(target))
target = GameObject.FindWithTag("Player");
}
Awake() 唤醒
Awake用于在游戏开始之前初始化变量或游戏状态。在脚本整个生命周期内它仅被调用一次.Awake在所有对象被初始化之后调用,所以你可以安全的与其他对象对话或用诸如GameObject.FindWithTag这样的函数搜索它们。每个游戏物体上的Awke以随机的顺序被调用。因此,你应该用Awake来设置脚本间的引用,并用Start来传递信息Awake总是在Start之前被调用。它不能用来执行协同程序。
private GameObject target;
void Awake()
{
target = GameObject.FindWithTag("Player");
}
OnEnable() 当可用
当对象变为可用或**状态时此函数被调用。
void OnEnable()
{
print("script was enabled");
}
Start() 开始
Start仅在Update函数第一次被调用前调用。
Start在behaviour的生命周期中只被调用一次。它和Awake的不同是Start只在脚本实例被启用时调用。你可以按需调整延迟初始化代码。Awake总是在Start之前执行。这允许你协调初始化顺序。
在所有脚本实例中,Start函数总是在Awake函数之后调用。
private GameObject target;
void Start()
{
target = GameObject.FindWithTag("Player");
}
FixedUpdate() 固定更新
当MonoBehaviour启用时,其FixedUpdate在每一帧被调用。
处理Rigidbody时,需要用FixedUpdate代替Update。例如:给刚体加一个作用力时,你必须应用作用力在FixedUpdate里的固定帧,而不是Update中的帧。(两者帧长不同)
为了获取自最后一次调用FixedUpdate所用的时间,可以用Time.deltaTime。这个函数只有在Behaviour启用时被调用。实现组件功能时重载这个函数。
void FixedUpdate()
{
rigidbody.AddForce(Vector3.up);
}
yield return new WaitForFixedUpdate
等待直到下一个固定帧速率更新函数。
public IEnumerator Awake()
{
yield return new WaitForFixedUpdate();
}
OnTriggerEnter() 当进入触发器
当Collider(碰撞体)进入trigger(触发器)时调用OnTriggerEnter。
这个消息被发送到触发器碰撞体和刚体(或者碰撞体假设没有刚体)。注意如果碰撞体附加了一个刚体,也只发送触发器事件。
OnTriggerEnter可以被用作协同程序,在函数中调用yield语句。
void OnTriggerEnter(Collider other)
{
Destroy(other.gameObject);
}
OnTriggerExit()
当Collider(碰撞体)停止触发trigger(触发器)时调用OnTriggerExit。
这个消息被发送到触发器和接触到这个触发器的碰撞体。注意如果碰撞体附加了一个刚体,也只发送触发器事件。
OnTriggerExit可以被用作协同程序,在函数中调用yield语句。
void OnTriggerExit(Collider other)
{
// 销毁所有离开触发器的物体
Destroy(other.gameObject);
}
OnTriggerStay()
当碰撞体接触触发器时,OnTriggerStay将在每一帧被调用。
这个消息被发送到触发器和接触到这个触发器的碰撞体。注意如果碰撞体附加了一个刚体,也只发送触发器事件。
OnTriggerStay可以被用作协同程序,在函数中调用yield语句。
void OnTriggerStay(Collider other)
{
// 对进入触发器的刚体施加一个向上的力
if (other.attachedRigidbody)
other.attachedRigidbody.AddForce(Vector3.up * 10);
}
OnCollisionEnter() 当进入碰撞
当此collider/rigidbody触发另一个rigidbody/collider时,OnCollisionEnter将被调用。
相对于OnTriggerEnter,OnCollisionEnter传递的是Collision类而不是Collider。Collision包含接触点,碰撞速度等细节。如果在函数中不使用碰撞信息,省略collisionInfo参数以避免不必要的运算。注意如果碰撞体附加了一个非动力学刚体,只发送碰撞事件。
OnCollisionEnter可以被用作协同程序,在函数中调用yield语句。
void OnCollisionEnter(Collision collision)
{
// 绘制所有接触点和法线
foreach (ContactPoint contact in collision.contacts)
{
Debug.DrawRay(contact.point, contact.normal, Color.white);
}
// 如果碰撞体有较大冲击就播放声音
if (collision.relativeVelocity.magnitude > 2)
audio.Play();
}
OnCollisionExit()
当此collider/rigidbody停止触发另一个rigidbody/collider时,OnCollisionExit将被调用。
相对于OnTriggerExit,OnCollisionExit传递的是Collision类而不是Collider。Collision包含接触点,碰撞速度等细节。如果在函数中不使用碰撞信息,省略collisionInfo参数以避免不必要的运算.注意如果碰撞体附加了一个非动力学刚体,只发送碰撞事件。
OnCollisionExit 可以被用作协同程序,在函数中调用yield语句。
void OnCollisionExit(Collision collisionInfo)
{
print("No longer in contact with " + collisionInfo.transform.name);
}
OnCollisionStay()
当此collider/rigidbody触发另一个rigidbody/collider时,OnCollisionStay将会在每一帧被调用。
相对于OnTriggerExit,OnCollisionExit传递的是Collision类而不是Collider。Collision包含接触点,碰撞速度等细节。如果在函数中不使用碰撞信息,省略collisionInfo参数以避免不必要的运算.注意如果碰撞体附加了一个非动力学刚体,只发送碰撞事件。
OnCollisionStay 可以被用作协同程序,在函数中调用yield语句。
void OnCollisionStay(Collision collisionInfo)
{
// 绘制所有接触点和法线
foreach (ContactPoint contact in collisionInfo.contacts)
{
Debug.DrawRay(contact.point, contact.normal, Color.white);
}
}
OnMouseXXX() 当鼠标XXX
当鼠标在GUIElement(GUI元素)或Collider(碰撞体)上执行相应动作时调用。
这个事件将发送给Collider或GUIElement上的所有脚本。
注意:此函数在iPhone上无效。
OnMouseDown |
当鼠标按下 |
OnMouseDrag |
当鼠标拖动 |
OnMouseEnter |
当鼠标进入 |
OnMouseExit |
当鼠标退出 |
OnMouseOver |
当鼠标经过 |
OnMouseUpAsButton |
当鼠标作为按钮弹起时 |
OnMouseUp |
当鼠标弹起 |
Update() 更新
当MonoBehaviour启用时,其Update在每一帧被调用。
Update是实现各种游戏行为最常用的函数。
void Update()
{
// 以每秒1米的速度向前移动物体
transform.Translate(0, 0, Time.deltaTime * 1);
}
yield return null
表示暂缓一帧,在下一帧接着往下处理,也有人习惯写成yield return 0或者yield return 1,于是误区就随之而来了,很多同学误认为yield return后面的数字表示的是帧率,比如yield return 10,表示的是延缓10帧再处理,实则不然,yield return num;的写法其实后面的数字是不起作用的,不管为多少,表示都是在下一帧接着处理。
IEnumerator Coroutine()
{
yield return null;
Debug.Log("Coroutine function");
}
yield return new WaitForSeconds
表示等待给定时间后继续接着往下处理,这个要注意的是实际时间等于给定的时间乘以Time.timeScale的值
IEnumerator Coroutine()
{
yield return new WaitForSeconds(1f);
Debug.Log("Coroutine function");
}
yield return WWW
表示剩余代码将在 www下载文件之后继续向下执行。
IEnumerator DownLoadImage()
{
//根据链接下载
WWW www =new WWW (imgurl);
//等待WWW代码执行完毕之后后面的代码才会执行。
yield return www;
//将下载的textrue在image上展示
image.texture = www.texture;
}
yield return StartCoroutine
等待一个新协程结束,开启另一个协程
IEnumerator Coroutine()
{
//等待开启另一个协程
yield return StartCoroutine(DownLoadImage());
Debug.Log("Coroutine...");
}
IEnumerator DownLoadImage()
{
//根据链接下载
WWW www =new WWW (imgurl);
//等待WWW代码执行完毕之后后面的代码才会执行。
yield return www;
//将下载的textrue在image上展示
image.texture = www.texture;
}
LateUpdate 晚于更新
当Behaviour启用时,其LateUpdate在每一帧被调用。
LateUpdate是在所有Update函数调用后被调用。这可用于调整脚本执行顺序。例如:当物体在Update里移动时,跟随物体的相机可以在LateUpdate里实现。
void LateUpdate()
{
// 以每秒1米的速度向前移动物体
transform.Translate(0, 0, Time.deltaTime * 1);
}
OnWillRenderObject 当渲染物体之前
如果对象可见每个相机都会调用它。
如果MonoBehaviour被禁用,此函数将不被调用。
此函数在消隐过程中被调用,在渲染所有被消隐的物体之前被调用。你可以用它来创建具有依赖性的纹理并且只有在被渲染的物体可见时才更新这个纹理。举例来讲,它已用于水组件中。
Camera.current将被设置为要渲染这个物体的相机。
// 当此transform被渲染时增大物体大小. 在运行模式下,
//注意在场景编辑器显示物体时,game面板和场景编辑器任何一个没有看到物体时,此函数是否被调用,
public GameObject otherObject;
void OnWillRenderObject()
{
otherObject.transform.localScale *= 1.0001F;
}
OnPreCull 当消隐之前
在相机消隐场景之前被调用。
消隐决定哪个物体对于相机来说是可见的.OnPreCull仅是在这个过程被调用。
只有脚本被附加到相机上时才会调用这个函数。
如果你想改变相机的参数(比如:fieldOfView或者transform),可以在这里做这些。场景物体的可见性将根据相机的参数在OnPreCull之后确定。
//把这个赋给相机.所有被它渲染的物体都被翻转.他只在pro版的Unity中有效.
void OnPreCull()
{
camera.ResetWorldToCameraMatrix();
camera.ResetProjectionMatrix();
camera.projectionMatrix = camera.projectionMatrix * Matrix4x4.Scale(new Vector3(1, -1, 1));
}
//设置它为true以便我们可以看到翻转的物体
void OnPreRender()
{
GL.SetRevertBackfacing(true);
}
//再设置它为false,因为我们不想作用于每个相机.
void OnPostRender()
{
GL.SetRevertBackfacing(false);
}
OnBecameVisible 当可见
当renderer(渲染器)在任何相机上可见时调用OnBecameVisible。
这个消息发送到所有附在渲染器的脚本上。OnBecameVisible 和 OnBecameInvisible可以用于只需要在物体可见时才进行的计算。
//当可见时开启行为
void OnBecameVisible()
{
enabled = true;
}
OnBecameInvisible 当不可见
当renderer(渲染器)在任何相机上都不可见时调用OnBecameInvisible。
这个消息发送到所有附在渲染器的脚本上。 OnBecameVisible 和 OnBecameInvisible可以用于只需要在物体可见时才进行的计算。
//当它不可见时禁用这个行为
void OnBecameInvisible()
{
enabled = false;
}
OnPreRender 当渲染之前
在相机渲染场景之前被调用。
只有脚本被附加到相机并被启用时才会调用这个函数。
注意:如果你改变了相机的参数(如:fieldOfView),它将只作用于下一帧.应该用OnPreCull代替.OnPreRender可以是一个协同程序,在函数中调用yield语句即可.
//这个脚本使你控制每个相机的雾
//通过开启和关闭检视面板中的脚本
//你可以开启和关闭每个相机的雾
private bool revertFogState = false;
void OnPreRender()
{
revertFogState = RenderSettings.fog;
RenderSettings.fog = enabled;
}
void OnPostRender()
{
RenderSettings.fog = revertFogState;
}
OnRenderObject 当渲染物体
在相机场景渲染完成后被调用。
该函数可以用来渲染你自己的物体,用Graphics.DrawMesh或者其他函数。这个函数类似于OnPostRender,除非OnRenderObject被其他物体用脚本函数调用,否则它是否附于相机都没有关系。
OnPostRender 当渲染之后
在相机完成场景渲染之后被调用。
只有该脚本附于相机并启用时才会调用这个函数。OnPostRender可以是一个协同程序,在函数中调用yield语句即。
OnPostRender在相机渲染完所有物体之后被调用。如果你想在相机和GUI渲染完成后做些什么,就用WaitForEndOfFrame协同程序。
OnRenderImage 当渲染图片
当完成所有渲染图片后被调用,用来渲染图片后期效果。
后期效果处理(仅Unity Pro)。
它允许你使用基于着色器的过滤器来处理最终的图像。进入的图片是source渲染纹理。结果是destination渲染纹理。当有多个图片过滤器附加在相机上时,它们序列化地处理图片,将第一个过滤器的目标作为下一个过滤器的源。
OnDrawGizmos 当绘制Gizmos
如果你想绘制可被点选的gizmos,执行这个函数。
这允许你在场景中快速选择重要的物体。
注意: OnDrawGizmos使用相对鼠标坐标。
//在物体的位置绘制一个灯泡图标
void OnDrawGizmos()
{
Gizmos.DrawIcon(transform.position, "Light Gizmo.tiff");
}
OnGUI 当界面
渲染和处理GUI事件时调用。
这意味着你的OnGUI程序将会在每一帧被调用。要得到更多的GUI事件的信息查阅Event手册。如果Monobehaviour的enabled属性设为false,OnGUI()将不会被调用。
void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 150, 100), "I am a button"))
print("You clicked the button!");
}
yield return WaitForEndOfFrame
等待直到所有的摄像机和GUI被渲染完成后,在该帧显示在屏幕之前。
你可以使用它读取显示到纹理,编码它为一个图片文件(参见Texture2D.ReadPixels和Texture2D.EncodeToPNG)并且发送到任意地方。
用WaitForEndOfFrame还可以让代码在LateUpdate的时序后调用。
OnApplicationPause 当程序暂停
当玩家暂停时发送到所有的游戏物体。
OnDisable 当不可用
当对象变为不可用或非**状态时此函数被调用。
当物体被销毁时它将被调用,并且可用于任意清理代码。当脚本编译完成之后被重加载时,OnDisable将被调用,OnEnable在脚本被载入后调用。
void OnDisable()
{
print("script was removed");
}
OnDestroy 当销毁
当MonoBehaviour将被销毁时,这个函数被调用。
OnDestroy只会在预先已经被**的游戏物体上被调用。
void OnDestroy()
{
print("Script was destroyed");
}
OnApplicationQuit 当程序退出
在应用退出之前发送给所有的游戏物体。
当用户停止运行模式时在编辑器中调用。当web被关闭时在网络播放器中被调用。