Unity3D 提供许多每帧回调,最常用的是Update. 还有一些较少使用的,如OnWillRenderObject、OnRenderObject和OnPostRender。关于这些回调的调用顺序,什么时候Time.frameCount递增?
我正在尝试将渲染完成后捕获的帧抓取与该帧中其他回调记录的对象属性同步。我发现,当OnPostRender被调用时,Time.frameCount已经递增,因此我收到通知的帧实际上是前一帧。因此,我想知道帧计数增加后还会调用哪些其他回调。
我编写这个脚本是为了捕获Time.frameCount更改的时间:
using UnityEngine;
public class OnFrameCounterDetector : MonoBehaviour {
int frameNumber = 0;
string prevMethod;
private void Awake() {
Time.fixedDeltaTime = 1 / 60;
prevMethod = System.Reflection.MethodBase.GetCurrentMethod().Name;
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnEnable() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void Start () {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void FixedUpdate() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void Update () {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void LateUpdate() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnWillRenderObject() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnPreCull() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnBecameVisible() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnBecameInvisible() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnPreRender() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnRenderObject() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnPostRender() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnRenderImage(RenderTexture source, RenderTexture destination) {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnDrawGizmos() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnGUI() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnApplicationPause(bool pause) {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void OnDisable() {
CheckFrameCount(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void CheckFrameCount(string callback) {
if (Time.frameCount > frameNumber) {
Debug.LogFormat("frameCount changed between {0} and {1}", prevMethod, callback);
frameNumber = Time.frameCount;
}
prevMethod = callback;
}
}
Run Code Online (Sandbox Code Playgroud)
OnGUI在编辑器中,我得到了OROnRenderObject和之间的更改FixedUpdate,但场景几乎是空的,只有一个摄像机和一个带有 的游戏对象Sprite Renderer。
区别在于,如果我选择了游戏对象或层次结构中的摄像机,如果选择了 GO,则将OnRenderObject发出信号,如果没有(即:保持在层次结构中选择摄像机)OnGUI,。
您可以在更详细的场景中使用此脚本,因为大多数回调在简单场景中根本不会被调用,对结果感到好奇。
顺便说一句,我没有费心添加具有各种收益的协程,但可以很容易地添加它们以捕获游戏循环中的更多“时刻”,例如 Update 和 LateUpdate 之间的时刻等。