Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is Time.frameCount incremented?

Tags:

unity3d

Unity3D offers many per-frame callbacks, the most used being Update. There are also lesser-used ones like OnWillRenderObject, OnRenderObject, and OnPostRender. With respect to the order in which these callbacks are called, when is Time.frameCount incremented?

I'm trying to synchronize frame-grabs I'm capturing after rendering completes with object properties recorded from other callbacks in that frame. I found that when OnPostRender is called, Time.frameCount has already been incremented, so that the frame I'm being notified of is actually the previous frame. For this reason, I'd like to know what other callbacks are called after the frame count has been incremented.

like image 303
Dan Hulme Avatar asked Oct 30 '22 04:10

Dan Hulme


1 Answers

I wrote this script in order to capture when Time.frameCount is changed:

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;
    }
}

Inside the editor, I got the change between OnGUI OR OnRenderObject and FixedUpdate, but the scene was almost empty, with just a single camera and a game object with a Sprite Renderer on it.

The difference was if I had the game object selected or the camera in the hierarchy, if the GO was selected, then OnRenderObject would be signaled, if not (i.e.: keep the camera selected in hierarchy), OnGUI.

You may use this script in more detailed scenes, since most of the callbacks aren't called at all in a simple scene, curious at the results.

BTW, I didn't bother to add coroutines with the various yields, they could be added though very easily to catch more "moments" in the game loop, like the one between Update and LateUpdate, etc.

like image 89
Galandil Avatar answered Jan 02 '23 21:01

Galandil