1

Our WebGL game made using Unity requires getting data from the body of a GET response. Currently this is implemented using a static class, with a blocking while loop to wait for the request to be done:

public static class NetworkController {
    public MyDataClass GetData() {
        UnityWebRequest webRequest = UnityWebRequest.Get(...);
        webRequest.SendWebRequest();
        while (!webRequest.isDone) {} // block here
        // Get body of response webRequest.downloadHandler.text and
        // return a MyDataClass object
    }
}

This works in the editor until later we discovered using WebGL disallows blocking the web request. Unity suggests using coroutines to mitigate that, but StartCoroutine() only exists in the MonoBehaviour class which our static class cannot inherit from.

Is there a way to continue the execution only after the web request gets a response while using a static class?


As per comments, the code is modified so now the static class makes a call to a MonoBehaviour singleton:

public static class NetworkController {
    public MyDataClass GetData() {
        return NetworkControllerHelper.GetInstance().GetData();
    }
}

public class NetworkControllerHelper : MonoBehaviour {
    /* ... GetInstance() method for creating a GameObject and create & return an instance... */

    private MyDataClass coroutineResult = null;

    public MyDataClass GetData() {
        UnityWebRequest webRequest = UnityWebRequest.Get(...);
        StartCoroutine(WebRequestCoroutine(webRequest));
        // How do I detect that the coroutine has ended then continue without hanging the program?
        while (coroutineResult == null) {}
        return coroutineResult;
    }

    // Coroutine for trying to get a MyDataClass object
    private IEnumerator WebRequestCoroutine(UnityWebRequest webRequest) {
        yield return webRequest.SendWebRequest();
        while (!webRequest.isDone) yield return new WaitForSeconds(0.1f);
        // Creating the MyDataClassObject
        coroutineResult = ...;
        yield break;
    } 
}

We need to wait for the resulting MyDataClass to be created, so we check if coroutineResult is null, but using a while loop to block hangs the program. How do I wait for a some seconds before checking for the loop condition?

HKJeffer
  • 209
  • 2
  • 11
  • We have one MonoBehavior singleton in our project and we use it to run all coroutines. It's a better design to use WebRequest asynchronously like it's meant to be though. – Retired Ninja Apr 26 '19 at 06:23
  • How do you hold the MonoBehaviour singleton? When I try to create the instance, Unity complains about MonoBehaviour needing to be attached to a GameObject. – HKJeffer Apr 26 '19 at 06:45
  • We have an object in the scene it is attached to. – Retired Ninja Apr 26 '19 at 07:02
  • To use untiy you sort of have to have at least one GameObject, good thing is ANY monobehaviour attatched to it can run a coroutine, while its body can live in a static class – zambari Apr 26 '19 at 07:35
  • Check this Url , you will find what you want :
    https://stackoverflow.com/questions/12224602/a-method-for-making-http-requests-on-unity-ios/12606963#12606963
    – Qusai Azzam Apr 26 '19 at 10:07

1 Answers1

2

You can't load a resource synchronously in WebGL as explained here.

Do not block on WWW or WebRequest downloads

Do not use code which blocks on a WWW or WebRequest download, like this:

while(!www.isDone) {}

Although, I cannot find a proper solution, I need 'webRequest.downloadHandler.text' and I want to use this string globally on another classes.

uerden
  • 176
  • 1
  • 13