- Home /
Multi-threading Alternative
Hello,
I would like to be able to call DynamicGI.UpdateEnvironment asynchronously somehow. Unfortunately this isn't possible in a new Thread, as I am given an error telling me that it can only be called in the main thread.
If anyone knows of any alternative ways to perform this task, please let me know!
I have heard you could possibly use a coroutine to do this, but I'm not quite sure how to go about using this method.
Any help or ideas would be appreciated.
Cheers.
I am not sure how Coroutines would help in the case since they are proceed using one thread. Check the link below: https://support.unity3d.com/hc/en-us/articles/208707516-Why-should-I-use-Threads-ins$$anonymous$$d-of-Coroutines-
Answer by JVene · Jul 07, 2018 at 05:37 AM
This situation comes about in a number of paradigms, including typical GUI based applications. For GUI's, one usually posts a message for the main UI thread to act upon.
The main thread in Unity is that which calls the various Update or FixedUpdate functions, so you can work this as simply as setting a bool (or some other state value) indicating the thread has requested a function to be called in the next Update or FixedUpdate of some appropriate object. Then, of course, that Update must read that bool, and call the function which performs DynamicGI.UpdateEnvironment, and resetting the bool.
You'll need to consider declaring that bool volatile, though quite often you won't really notice why that is important. I'll leave you to search the keyword to dive into the general topic of threading if it is unfamiliar.
Of course, this is all too simple if there are many such functions to call. An alternative, more generalized approach might be to create a class representing a delegate and parameters, possibly using generics if required. In this way threads could post such an object to a queue owned by an appropriate object. The queue represents a list of functions to be called on the main thread, probably in the next update.
Such a queue would require the kind of protections typical of threaded programming, as it will be accessed by competing threads. The design is beyond the scope of a post, but the basic idea is to use an array, likely constructed as a circular queue, or some kind of deque container, to receive requests from various threads. The Update function would then consume this container, performing each function in the list, leaving it empty.
There is a class created by pdwitte (search for UnityMainThreadDispatcher) that provides a service for this kind of situation.
Thanks for the answer.
This seems alot more difficult than I thought it would be, to the point where I might try avoid it. I should've mentioned, the reason why I wanted to call DynamicGI.UpdateEnvironment from another thread was to prevent blocking the main thread, as it causes the game to 'freeze' due to the intense calculations it performs. So doing something like setting a bool would still call from the main thread, not achieving what I was hoping to achieve.
Since I was using DynamicGI.UpdateEnvironment for a day-night cycle, I decided to try write a script which caches the ambient probe at the different skybox states (Sunrise, mid-day, sunset, and night), lerps between them based on the time, then sets the RenderSettings.ambientProbe to it. The result of doing this was actually better than I expected, and there is barely any performance hit doing it this way (Apart from in the Start method, I had to call DynamicGI.UpdateEnvironment four times in total) So I may stick with this method ins$$anonymous$$d.
Thanks again for your input.
Your answer
Follow this Question
Related Questions
How to update a progress bar for ANY asynchronous operation? 2 Answers
Multi threading problem ! 2 Answers
Optimizing the generation of a procedural world - 50ms lag spike to 1 Answer
Does UnityEngine.CustomeYieldInstruction works in a seperate thread? 2 Answers
Couroutines and Threading for Procedural Generation 1 Answer