-2

I have a function in unity that makes a request for a server, and for each value in the result, it should call a function to add a image on a list and get an object from the same server and add on another list

    public void SaveServer() {
        string serverAddress = inputField.text;
        GlobalStateData.getInstance().ServerAdress = serverAddress;
        StartCoroutine(Utils.GetRequest(GlobalStateData.getInstance().ServerAdress + "file/ObjectController/",
            (UnityWebRequest) => {
                JArray jsonResponse = JArray.Parse(UnityWebRequest.downloadHandler.text);
                foreach (var json in jsonResponse) {
                    String base64 = (string)json["trackingImage"]["file"]["base64"];
                    String name = (string)json["file"]["name"];
                    int objectId = (int)json["id"];
                    Texture2D texture = Utils.Base64ToTexture2D(base64);

                    StartCoroutine(addImageAndObject(objectId, texture, name));
                }
                Debug.Log(jsonResponse);
                transform.parent.Find("canvas_MainMenu").gameObject.SetActive(true);
                gameObject.SetActive(false);
            }));
    }

    private IEnumerator addImageAndObject(int objectId, Texture2D texture2D, String name) {
        StartCoroutine(addImage(texture2D, name));
        yield return AddObjectById(objectId, name).MoveNext();
    }

but in the AddObjectById the method is stopping before complete the request

    private IEnumerator AddObjectById(int id, string name) {
        string url = GlobalStateData.getInstance().ServerAdress + "bundle/ObjectBundleController/" + id;
        
        UnityWebRequest get = UnityWebRequest.Get(url);
        yield return get.SendWebRequest(); // it stops here
        if (get.result != UnityWebRequest.Result.Success) {
            Debug.Log(get.error);
            yield return false;
        }
        else {
            AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(get);
            GameObject obj = (GameObject)bundle.LoadAsset(name);
            _place3DObjectRef.ArPrefabs.Add(obj);   
            yield return true;
        }
    }

I didn't understand how my GetRequest Method Works and the AddObjectById

Here is the GetRequest

    public static IEnumerator GetRequest(string server, Action<UnityWebRequest> successCallback, Action<String> errorCallback = null) {
        UnityWebRequest get = UnityWebRequest.Get(server);
        yield return get.SendWebRequest();
        if (get.result != UnityWebRequest.Result.Success) {
            Debug.Log(get.error);
            if(errorCallback != null)
                errorCallback("Cannot make request to " + server +
                          "\nerror:" + get.error);
            yield return false;
        }
        else {
            successCallback(get);
            yield return true;
        }
    }

and this one runs fine. What should I do to the method to not stops after the first yield return?

EDIT: I solved the problem! The reason why this was happening, it was because the gameObject was setting deactivated before the coroutine finishes, so the scripts was stopping

gameObject.SetActive(false);

https://docs.unity3d.com/ScriptReference/GameObject.SetActive.html The unity documentation says that "Deactivating a GameObject disables each component, including attached renderers, colliders, rigidbodies, and scripts. For example, Unity will no longer call the Update() method of a script attached to a deactivated GameObject. OnEnable or OnDisable are called as the GameObject received SetActive(true) or SetActive(false)." So, as the script is an component attached to the scene object, makes sense that it stops working

derHugo
  • 83,094
  • 9
  • 75
  • 115

2 Answers2

1

Well, yield works by returning results from one iteration,and what comes after will not be executed. In your method, when a call is made to AddObjectById, it will stop at the first yield it finds and return its value, in this case get.SendWebRequest();, not continuing the flow. If you move yield return get.SendWebRequest(); after of if-else, it will never enter, as it will have some return in yield return coming from "if-else".

0

I found out that if the gameObject is not active gameObject.SetActive(false); the Coroutines stops too. The problem was not with the coroutines but with the gameObject being deactivated