Jump to content

Can .invoke be delayed until the game isn't busy?


Recommended Posts

Is there an easy way to tell how busy Unity is?

Over at this thread I was told about a good idea, that if I monitor when the game unpauses, I can check for changes in the difficulty settings (e.g. to enable and disable an add-on).

The unpause thing also happens (sometimes) when the scene changes e.g. the transition from Space Center scene to Main Menu scene. I thought I would like to delay the processing until the scene change was done, so I did a Unity '.Invoke ("name", 1.0)' to postpone my handler code for a second.

To my surprise Unity is quite keen on doing a good job timing-wise and one second later, (less than) halfway through the scene change, my handler is invoked. Ok, so it sounds silly to complain that I got what it said on the tin! Still, what I was aiming for wasn't quite to delay execution for only half a scene change.

I guess I could explicitly monitor say 'GameEvents.onGameSceneLoadRequested' and 'GameEvents.onLevelWasLoaded'. Is that a terrible idea? Is there a better way?

Link to comment
Share on other sites

I was wondering how best to do stuff that is not time critical. Maybe I got a bit carried away. I haven't got any code yet.

The example that I was playing with was to detect when difficulty settings are changed, and then update some mod variables (or maybe disable the mod). If the player changes settings and it takes a few seconds before it is detected that is just fine. So I imagined some sort of loop (or more specifically to the above case, monitor every game unpause), and then the trick would be to run the loop when the rest of the game is least busy.

A more useful scenario may be to check if some contract is fulfilled yet. Let us say the contract is to make sure you have 6 satellites in a particular constellation relative to each other. Let us say to determine if the condition is satisfied requires 'heavy calculation'. Let us also assume that it is not important to detect contract success right away, if we can mange to check once a minute that is fine.

Since the last post I peeked at the Contract Configurator code, and there it seemed some of the trick is to run a bit of code in Update, but only every 20th frame. (if I read it correctly).

Is that how you would do it? Count frames?

Link to comment
Share on other sites

On 19/2/2017 at 11:10 AM, Rodhern said:

I was wondering how best to do stuff that is not time critical. Maybe I got a bit carried away. I haven't got any code yet.

The example that I was playing with was to detect when difficulty settings are changed, and then update some mod variables (or maybe disable the mod). If the player changes settings and it takes a few seconds before it is detected that is just fine. So I imagined some sort of loop (or more specifically to the above case, monitor every game unpause), and then the trick would be to run the loop when the rest of the game is least busy.

A more useful scenario may be to check if some contract is fulfilled yet. Let us say the contract is to make sure you have 6 satellites in a particular constellation relative to each other. Let us say to determine if the condition is satisfied requires 'heavy calculation'. Let us also assume that it is not important to detect contract success right away, if we can mange to check once a minute that is fine.

Since the last post I peeked at the Contract Configurator code, and there it seemed some of the trick is to run a bit of code in Update, but only every 20th frame. (if I read it correctly).

Is that how you would do it? Count frames?

Well, I think that if you do heavy calculations, then creating a new thread would be the way to go (example can be found in the linked GitHub code below).

If the calculation is light using update() could be fine, many modders use this approach where they check for simply criteria.

On 18/2/2017 at 4:40 PM, Rodhern said:

I guess I could explicitly monitor say 'GameEvents.onGameSceneLoadRequested' and 'GameEvents.onLevelWasLoaded'. Is that a terrible idea? Is there a better way?

You can easily subscribe to an event like the above ones which is a great way of having you code only run on demand. And if a suitable event already exists then that would be my recommendation.

Coroutines can be used if you want some code to run much less that e.g. the update() or fixedupdate(). Coroutines are apparently much less demanding than using "Invoke", according to the research I've done on related topics. You can have the coroutine only run e.g. every 5 seconds if that is what is needed. I do think that could be more efficient that counting frames, though both should be quite light.

If you need a custom event, I would recommend reading this thread

I also posted some question regarding throttle event, where there might be some interesting facts.

Furthermore, I created the onThrottleChange event, which you can look at if you go for a custom event

https://github.com/WarezCrawler/Guybrush101/blob/master/GTI_Utilities/GTI_Events.cs

The code also have an example on subscribing to an event.

Subscribe: https://github.com/WarezCrawler/Guybrush101/blob/master/GTI_Utilities/GTI_Events.cs#L58-L63

Subsciber: https://github.com/WarezCrawler/Guybrush101/blob/master/GTI_Utilities/GTI_Events.cs#L195-L204

I know the code is commented out, but that is only because it was not for the final release, only for testing purposes.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...