Is it possible to schedule a coroutine to run at the time of LateUpdate?

I have some graphical indicators that I need to run at a lateupdate, they simply need to get calculated after everything else, but I also don’t want the LateUpdate to run every frame to check if there is anything to update.

WaitForEndOfFrame doesn’t work since it will run after the GUI is updated.

Didn’t find any documentation on it being possible to enable and disable the LateUpdate function, so if anyone has any idea how to solve this please let me know :).

I’d do something like this:

float lastUpdate;
float updateInterval = 1.0f;

void LateUpdate()
{
   if (Time.time > lastUpdate + updateInterval)
   {
      RefreshIndicators();
      lastUpdate = Time.time;
   }
}

I’m already doing a check in my current LateUpdate() to see if anything needs updating - which only checks if a boolean is true - but thanks anyway :).

Well the cost of checking a boolean every frame is small, as long as it isn’t a property using a complex Get implementation, I’d just stick with that.

That’s true but I want to try to optimize my code as much as I can. However if it’s not possible I’ll just stick with the boolean, but we’ll see if anyone has a solution :).

The way you are doing it is already the fastest.

A solution involving a coroutine would be way less optimal.

No matter how you slice it, weather its in your code or somewhere else, something needs to be checked every frame.

2 Likes

Ok, thanks for the input.

Check out @lordofduct 's frame work. He has hooks all over the place for various events. If you are interested in doing this a lot, its worth writing some of your own frame work.

1 Like

So, I’m not sure what your design is. But I’m going to guess that the operation that occurs in ‘LateUpdate’ only occurs on some other event.

Like:

private bool _needsUpdate = false;
      
void SignalChange()
{
    _needsUpdate = true;
}

void LateUpdate()
{
    if (_needsUpdate)
    {
        //perform some task
        _lateUpdate = false;
    }
}

This method might be called very infrequently, so you don’t want to waste checking if ‘needsUpdate’ every frame if it happens once a minute or something?

Am I correct in assuming this?

If this is so, it is true, BenZed is correct in that something has to poll the LateUpdate event, because it’s the only hook into that event that exists.

Personally I have a global Singleton that I use to hook into the events. This way each is only polled as few times as I need… instead of EVERY script polling it every frame.

This is it:

I actually poll 3 times per update type. An early one (script flagged to operate at order -32000), a normal (script not given an execution order), and a script that is flagged to operate last (32000 execution order). This way I can hook in at any point.

I always did it with .net events (as you can see the static ‘event’ members of GameLoopEntry).

But I recently added a way to call a single function one time, and wanted it to have multithreading support. So that way from a separate thread I could just call back to the main thread and do something.

That’s what I wrote the ‘InvokePump’ for:

I gave GameLoopEntry 2 pumps, one for ‘Update’ and one for ‘FixedUpdate’. I never actually added one for ‘LateUpdate’ though, as I never really use ‘LateUpdate’ for anything. But it could be easily added… just mirror the way ‘Update’ and ‘FixedUpdate’ do it:

        //Update

        private void Update()
        {
            //Track entry into update loop
            _currentSequence = UpdateSequence.Update;

            if (_internalEarlyUpdate != null) _internalEarlyUpdate(false);

            _invokePump.Update();

            if (EarlyUpdate != null) EarlyUpdate(this, System.EventArgs.Empty);
        }

        //Fixed Update

        private void FixedUpdate()
        {
            //Track entry into fixedupdate loop
            _currentSequence = UpdateSequence.FixedUpdate;

            if (_internalEarlyUpdate != null) _internalEarlyUpdate(true);

            _fixedInvokePump.Update();

            if (EarlyFixedUpdate != null) EarlyFixedUpdate(this, System.EventArgs.Empty);
        }

        //LateUpdate

        private void LateUpdate()
        {
            _currentSequence = UpdateSequence.LateUpdate;
           
            //INSERT INVOKEPUMP UPDATE CALL HERE
           
            if (EarlyLateUpdate != null) EarlyLateUpdate(this, System.EventArgs.Empty);
        }

Then the syntax would simply be:

void SignalChange()
{
    GameLoopEntry.LateUpdatePump.BeginInvoke(this.PerformOnLateUpdate);
}

void PerformOnLateUpdate()
{
    //perform some task
}
4 Likes

Hi. I just noticed the post and I will have to read it tomorrow, gonna hop into bed now. Thanks for the reply.

After having read your code I have decided to just disable the script when it’s not needed instead, since the script will only be needed for like a minute at a time, and then rest for a few minutes. You’ve done a very nice job but I was hoping for some easy solution :slight_smile: (I’m still very new to unity and programming). But I have bookmarked this page and will come back to it once I get more knowledge. Thank you.

1 Like