- Home /
Async Calculations in a level
Hey there!
So I'm trying to make a script at the game startup (Lets call it Scene 0) where the script checks the current screen resolution and scales the gui dimensions at start, while showing a progress bar/circle. I've been checking the Application.LoadLevelAsync, but I believe that's only good for loading an entire level, not to run a script.
So, is there any way to run a script in a Asyncronous way?
Thanks in advance, João Borrego.
Answer by Briksins · Dec 17, 2013 at 11:57 AM
you can use Async - native C# functionality, it is nothing to do with Unity however it is depends on the Unity main thread, and if you try to execute Unity Thread depending stuff (for example: WWW or WWWForm) you will get error. However even than could be ignored and manually implemented through native C# WebClient class
it is slightly complex and require use of C# delegates, also actual class where you going to implement async routine shouldn't extend MonoDeveloper class
here is example:
Lets say we create simple C# script and attach it to the Main Camera
MyAsyncExecutor.cs - Class to attache to Main Camera
public class MyAsyncExecutor: MonoBehaviour {
// Use this for initialization
void Start () {
AsyncController ac = new AsyncController();
ac.StartAsyncCalculation();
}
// Update is called once per frame
void Update () {
}
}
Create AsyncController.cs class NOTE: dont extend MonoDeveloper
public class AsyncController {
//int is async return type //arguments
private delegate int AsyncCalculatorDelegator(int dig1, int dig2);
public void StartAsyncCalculation()
{
// Create delegate and define what it going to do
//in this example it will call "int AsyncCalculator.Calculate(int, int)"
AsyncCalculatorDelegator myDelegate = new AsyncCalculatorDelegator(new AsyncCalculator.Calculate);
int dig1 = 10;
int dig2 = 20;
//Now Execute it asynchronously by passing arguments and defining event response method
myDelegate.BeginInvoke(dig1, dig2, new AsyncCallback(CalculationResponse), null);
}
public void CalculationResponse(IAsyncResult result)
{
//lazy recast
AsyncResult res = (AsyncResult)result;
//getting delegate back
AsyncCalculatorDelegator myDelegate = (AsyncCalculatorDelegator)res.AsyncDelegate;
//getting actual result from async calculation
int sumResult = myDelegate.EndInvoke(result);
//now you can do with sumResult whatever you want as it was calculated Async-ly
}
}
Finally create class where you will do actual calculation: AsyncCalculator.cs
public class AsyncCalculator {
public int Calculate(int dig1, int dig2)
{
//do your calculations here
//and return result as declared type
//in this case it should be int
int sum = dig1 + dig2;
return sum;
}
}
here you are :) you did sum calculation in async way :)
There are new features in .Net 4.5 with use of "async" "Task" and "await" it is much easier to use it, however im not sure yet how Unity will handle it, as Unity create by default C# project in .Net 3.5 and "Task" is not available in 3.5
as you see there are 4 other ways of implementing parallel calculations which I found so far, they are:
"StartCorutine", "IEnumereble" and "yield" - native Unity thing
"Delegates", "BeginEnvoke" and "EndEnvoke" - example I showed
"Task" and "await" = new thing in .Net 4.5
"Threads" - never look at it yet in C#
Well, lets hope this fits the glove! Since most of those operations are read from file, and then return the contents, it might be perfect :P
Answer by InfiniBuzz · Jul 02, 2013 at 03:46 PM
Have you tried / thought of using a coroutine and events?
As InfiniBuzz mentioned, coroutines are somewhat asynchronous, in that they can be paused between frames. This is probably your best bet.
I feel it's worth mentioning that you can also use threads with Unity, but the Unity API itself is not thread safe, so you can only do things in Unity from the main thread. Other threads can be used if you're doing intensive calculations (e.g. for AI) that you want to run in parallel.
I already considered using Coroutines, but aren't they frame dependent, too? I mean, everytime I use a coroutine, I usually include a "yield WaitFor..." or something like that...
What do you mean exactly frame dependent?
Give more infaormation about what you want to do?
1) Load a gamescene and display a loading overlay till the scene is fully loaded? (this is basically not possible)
2) Load a "splashScreenScene" first and do calculations and then load the gamescene? In this you can use coroutines but also do it "normally".
Actually 1 is possible and I've done it multiple times, even with full animation
Your answer
Follow this Question
Related Questions
getting udp package info inside unity (GlovePIE) 0 Answers
Help; I have two code errors need adivce 0 Answers
End game then an Object is close to another object? 0 Answers
Scripting error #2! 2 Answers
get all scripts attached to gameobject 2 Answers