- Home /
Use Coroutine in Batchmode
I am writing a build script that is lunched from the command line with -quit -batchmode -executeMethod
and I want to use a UnityWebRequest
to obtain stuff from my server. Is there a way to launch a coroutine and wait for it to finish in such a static method script or will I need to rely on threads and the god awful HttpWebRequest of .net 3.5?
Answer by FlaSh-G · Sep 06, 2017 at 10:26 AM
I doubt that Update, and with that coroutines, work in this context. But it should work to just wait for a WWW or UnityWebRequest to finish. Afaik, they are not bound to be stuffed into a coroutine in any way.
Here's some example code (with WWW, but the idea is the same) you could try:
public static void Foo()
{
var www = new WWW(url);
while(!www.isDone)
{
Thread.Sleep(100);
}
DoStuffWith(www);
}
I have just tried this solution now, however, the async operation is never "done". I suspect that since the control never returns to the main update loop, the download is simply never started. In an other framework, I know that to make this work I need to manually invoke processing of the main event loop to have async operations complete.
I tried this with Unity 2017 and it worked fine. I tested it by calling Foo() from start, and also from a console with -quit -batchmode -whatnot.
It doesn't work with this code:
static private bool DownloadUnityFile(string destPath, string url)
{
var webRequest = UnityWebRequest.Get(url);
webRequest.downloadHandler = new DownloadToFile(destPath);
var asyncOperation = webRequest.Send();
var startTime = DateTime.Now;
while (!asyncOperation.isDone)
{
if ((DateTime.Now - startTime).TotalSeconds > 120)
return false;
Thread.Sleep(200);
}
return !webRequest.isNetworkError;
}
Answer by fkorsa · Aug 23, 2019 at 01:16 PM
To make it work, you need to remove the -quit flag from your command line invocation and instead call EditorApplication.Exit when the build is finished. That way, Unity will not exit when the static method you invoked has finished executing, and you can use your static method to start a coroutine instead. Like so:
private class EditorCoroutine
{
private IEnumerator routine;
private EditorCoroutine(IEnumerator routine)
{
this.routine = routine;
}
public static EditorCoroutine Start(IEnumerator routine)
{
EditorCoroutine coroutine = new EditorCoroutine(routine);
coroutine.Start();
return coroutine;
}
private void Start()
{
UnityEditor.EditorApplication.update += Update;
}
public void Stop()
{
UnityEditor.EditorApplication.update -= Update;
}
private void Update()
{
if (!routine.MoveNext())
{
Stop();
}
}
}
public static class AutomatedBuilder
{
// Invoke that one from the command line
public static void Build()
{
EditorCoroutine.Start(BuildImpl());
}
private static System.Collections.IEnumerator BuildImpl()
{
// Your build code here...
yield return null;
EditorApplication.Exit(0);
}
}
Answer by hugeandy · Jun 23, 2021 at 05:08 PM
A soultion to this if you cannot remove the -quit option (like if you are running automated builds with TeamCity) is to run a coroutine "manually" like this:
public static void BuildMethod() {
var it = CoroutineMethod();
while (it.MoveNext()) { }
//done here and unity will exit
}
Your answer
Follow this Question
Related Questions
How to display a message, wait for keypress and again and again? 1 Answer
Make multiple Projectiles move at the same Time... 0 Answers
How to stop a coroutine started in Script A from within Script B 1 Answer
Removing the last element in an ArrayList; C# 1 Answer
Problem destroying cloned prefabs 1 Answer