pperuzzo
pperuzzo

Reputation: 65

Call a IEnumerator method from another script in Unity and get its return value

I'm working on a project in Unity. I have this file:

API.cs (no attached to any GameObject)

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using LitJson;

public class API : MonoBehaviour
{

    public IEnumerator Login(string email, string psw)
    {
        string URL = "https://####.azurewebsites.net/api/login";
        WWWForm form = new WWWForm();
        form.AddField("email", email);
        form.AddField("password", psw);

        var download = UnityWebRequest.Post(URL, form);

        // Wait until the download is done
        yield return download.SendWebRequest();

        if (download.isNetworkError || download.isHttpError)
        {
            print("Error downloading: " + download.error);
        }
        else
        {
            JsonData data = JsonMapper.ToObject(download.downloadHandler.text);
            string token = (string)data["success"]["token"];
            Debug.Log(token);
        }
    }
}

caller.cs (attached to a GameObject in the current scene)

    private void Start ()
    {
        // Something like this
        var token = API.Login("[email protected]", "####");
    }

My question is: How can I call the function "Login" in caller.cs and retrieve the value of the token?


What I have tried and didn't work:


EDIT 1:

Was able to solve the problem of calling the method from another script, the problem was that I had to create an object and attach to it API.cs. Then I also had to drag and drop that object in the public field of caller.cs in the inspector. Moreover, I had to add in caller.cs the Login method inside the StartCoroutine() one.

Still, have to figure out now how to retrieve the value of the token from the Login() method.

Upvotes: 2

Views: 3419

Answers (1)

Programmer
Programmer

Reputation: 125305

Was able to solve the problem of calling the method from another script, the problem was that I had to create an object and attach to it API.cs. Then I also had to drag and drop that object in the public field of caller.cs in the inspector.

That doesn't sound right dragging and dropping the script manually in the Editor since your goal is to do with from script. The API script is a MonoBehaviour because it derives from it. Use AddComponent to add the API class then call StartCoroutine on the Login function.

API api = gameObject.AddComponent<API>();
StartCoroutine(api.Login("[email protected]", "####"));

Remove the MonoBehaviour so that you don't have to attach the API script to a GameObject instead create new objects with the new keyword.

public class API 
{

    public IEnumerator Login(string email, string psw)
    {
        ....
    }
}

Noe, you can simply do:

API api = new API();
StartCoroutine(api.Login("[email protected]", "####"));

Finally, to return the value, add Action as third param.

public class API
{

    public IEnumerator Login(string email, string psw, Action<string> token)
    {
        string URL = "https://####.azurewebsites.net/api/login";
        WWWForm form = new WWWForm();
        form.AddField("email", email);
        form.AddField("password", psw);

        var download = UnityWebRequest.Post(URL, form);

        // Wait until the download is done
        yield return download.SendWebRequest();

        if (download.isNetworkError || download.isHttpError)
        {
            Debug.Log("Error downloading: " + download.error);
        }
        else
        {
            JsonData data = JsonMapper.ToObject(download.downloadHandler.text);
            string tokenResult = (string)data["success"]["token"];
            Debug.Log(tokenResult);
            if (token != null)
                token(tokenResult);
        }
    }
}

To call it from your non coroutine function:

API api = new API();
StartCoroutine(api.Login("[email protected]", "####", (token) =>
{
    Debug.Log("Token: " + token);
}
));

Upvotes: 4

Related Questions