Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use RestClient on Editor without running the game #121

Open
Rafarel opened this issue Mar 13, 2020 · 17 comments
Open

Use RestClient on Editor without running the game #121

Rafarel opened this issue Mar 13, 2020 · 17 comments

Comments

@Rafarel
Copy link

Rafarel commented Mar 13, 2020

First of all, thank you for your amazing work on the Rest Client for Unity !
I'm using it in my game to send all the players replay data to my Rest API and it works like a charm !

Today I'm making a Unity Editor Window to browse all data on my Rest API and launch a replay from any data retrieved by the API.
I'm wondering how I could get your Client working in an Editor script without the game running ?

Thanks for your help, have a nice day !

@jdnichollsc
Copy link
Member

jdnichollsc commented Mar 13, 2020

Hello Rafarel,
One little question, do you know if is possible to use the UnityWebRequest system of Unity without running the game?
It looks like you can => #22

Thanks for using this Unity asset, let me know! 👍

@Rafarel
Copy link
Author

Rafarel commented Mar 14, 2020

It looks like the main reason you need the game running is to be able to access a coroutine.
Unity have an "editor coroutine" official package in preview available in the package manager, I think this is a good start :)

@jdnichollsc
Copy link
Member

Ohh interesting, let me check! 👍

@TiborUdvari
Copy link

I'm trying to do this as well to download images from airtable for an AR experience. Import them into the assets and generate prefab variants and upload them to Unity Cloud Delivery. Anyway, I haven't gotten it to work yet, but there is a promising answer at the end here: https://answers.unity.com/questions/1403050/use-coroutine-in-batchmode.html

@TelloViz
Copy link

TelloViz commented Dec 27, 2021

Unity has editorCoroutines now. You can use these with unitywebrequests and I've been successful in doing so for downloading Pokemon TCG data from a rest api. I am not sure how to make Rest use the EditorCoRoutine though...

@jdnichollsc
Copy link
Member

Unity has editorCoroutines now. You can use these with unitywebrequests and I've been successful in doing so for downloading Pokemon TCG data from a rest api. I am not sure how to make Rest use the EditorCoRoutine though...

Hello mate, can you share your example using UnityWebRequest system directly?

Thanks for your collaboration!

@TelloViz
Copy link

TelloViz commented Dec 27, 2021

I've been fumbling around learning how to use networking stuff for the first time, It's been pretty educational struggling up until now lol. I just now need to figure out how to use RestClient with editorcoroutines and I'd be golden

I was originally just ignorantly using RestClient in an editorwindow without realizing the difference between EditorWindows and Monos... So my editor window was generating tons of static coroutines

@TelloViz
Copy link

TelloViz commented Dec 27, 2021

Unity has editorCoroutines now. You can use these with unitywebrequests and I've been successful in doing so for downloading Pokemon TCG data from a rest api. I am not sure how to make Rest use the EditorCoRoutine though...

Hello mate, can you share your example using UnityWebRequest system directly?

Thanks for your collaboration!

editorCoroutine = EditorCoroutineUtility.StartCoroutineOwnerless(GetRequest(host, (UnityWebRequest req) =>
        {
            if (req.result != UnityEngine.Networking.UnityWebRequest.Result.Success)
            {
                Debug.Log($"{req.error}: {req.downloadHandler.text}");
            }
            else
            {

                text = host + "\n";

                if (searchType[selGrid] == "Sets")
                {
                    Debug.Log("You searched by selection type: SETS");
                    setsRespo = JsonConvert.DeserializeObject<SetsResponseObject>(req.downloadHandler.text);

                    foreach (var item in setsRespo.data)
                    {
                        PrintSetData(item);
                    }
                }
                else if (searchType[selGrid] == "Cards")
                {
                    Debug.Log("You searched by selection type: CARDS");
                    cardsRespo = JsonConvert.DeserializeObject<Card_ResponseObject>(req.downloadHandler.text);
                    foreach (var item in cardsRespo.data)
                    {
                        PrintCardData(item);
                    }
                }

EDIT!!!! ALMOST FORGOT A PART OF CODE::

IEnumerator GetRequest(string url, Action<UnityWebRequest> callback)
    {
        Debug.Log("GetRequest() called inside coroutine");
        using (UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.Get(url))
        {
            // Send the request and wait for a response
            yield return request.SendWebRequest();
            callback(request);
        }
    }

So this is how I started using webrequest directly instead of RestClient package... problem is, restclient takes your paramaters and headers in the RequestHelper but I am not sure yet how to send that information to the UnityRequest system or to just make RestClient operate with EditorCoroutines...

text that is assigned to above, is then assigned to a text field in the ongui method

@TelloViz
Copy link

With RestClient I'm able to instantiate a RequestHelper that internally parameterizes my url+params...

 RequestHelper requestOptions = new RequestHelper
        {
            Uri = host + searchTypeString/*inURL*/,
            Method = "GET",
            Timeout = 10,
            Params = new Dictionary<string, string> {
                { "q", query },
                {"page", page },
                {"pageSize", pageSize },
                {"orderBy", orderBy }
            },
            Headers = new Dictionary<string, string> { { apiKeyName, apiKeyValue } },
            ContentType = "application/json", //JSON is used by default
            Retries = 3, //Number of retries
            RetrySecondsDelay = 2, //Seconds of delay to make a retry
            RetryCallback = (err, retries) => { }, //See the error before retrying the request
            EnableDebug = true, //See logs of the requests for debug mode
            IgnoreHttpException = true, //Prevent to catch http exceptions
            UseHttpContinue = true,
            RedirectLimit = 32
        };

I am not sure how to provide this information to the WebRequestSystem directly. So using EditorCoroutines + RestClient would be ideal...

@TelloViz
Copy link

TelloViz commented Dec 27, 2021

image

Here is an image of my editor window, the text field at the bottom left is text as seen in code above, an image prints the the right of it representing the card front. When I was using RestClient, I could plug each of these fields into the RequestHelper object and that would handle concatenating it properly.

@jdnichollsc
Copy link
Member

I think we can add a new option from RequestHelp in order to use EditorCoroutineUtility.StartCoroutineOwnerless instead of StaticCoroutine.StartCoroutine, in the meantime you can try this:

RequestHelper options = new RequestHelper();
editorCoroutine = EditorCoroutineUtility.StartCoroutineOwnerless(
    HttpBase.DefaultUnityWebRequest(options, (err, response) => {
        if (err != null) {
            EditorUtility.DisplayDialog("Error Response", err.Response, "Ok");
        } else {
            EditorUtility.DisplayDialog("Response", response.Text, "Ok");
        }
    });
);

Let me know, it works in my mind 😄

@TelloViz
Copy link

@TelloVisionGames do you want to have a meeting to review this? sounds interesting, please schedule a meeting here https://calendly.com/jdnichollsc

Best, Juan

For sure. Let me try out the things you kindly suggested and let you know.

-Josh

@TelloViz
Copy link

I think we can add a new option from RequestHelp in order to use EditorCoroutineUtility.StartCoroutineOwnerless instead of StaticCoroutine.StartCoroutine, in the meantime you can try this:

RequestHelper options = new RequestHelper();
editorCoroutine = EditorCoroutineUtility.StartCoroutineOwnerless(
    HttpBase.DefaultUnityWebRequest(options, (err, response) => {
        if (err != null) {
            EditorUtility.DisplayDialog("Error Response", err.Response, "Ok");
        } else {
            EditorUtility.DisplayDialog("Response", response.Text, "Ok");
        }
    });
);

Let me know, it works in my mind 😄

I had to adjust your closing parens and brackets at the end but it worked like a charm. Super quick response too!

my code snippet now:


RequestHelper requestOptions = new RequestHelper
        {
            Uri = host + searchTypeString/*inURL*/,
            Method = "GET",
            Timeout = 10,
            Params = new Dictionary<string, string> {
                { "q", query },
                {"page", page },
                {"pageSize", pageSize },
                {"orderBy", orderBy }
            },
            Headers = new Dictionary<string, string> { { apiKeyName, apiKeyValue } },
            ContentType = "application/json", //JSON is used by default
            Retries = 3, //Number of retries
            RetrySecondsDelay = 2, //Seconds of delay to make a retry
            RetryCallback = (err, retries) => { }, //See the error before retrying the request
            EnableDebug = true, //See logs of the requests for debug mode
            IgnoreHttpException = true, //Prevent to catch http exceptions
            UseHttpContinue = true,
            RedirectLimit = 32
        };

        
        editorCoroutine = EditorCoroutineUtility.StartCoroutineOwnerless(
            HttpBase.DefaultUnityWebRequest(requestOptions, (err, response) => {
                if (err != null) {
                    EditorUtility.DisplayDialog("Error Response", err.Response, "Ok");
                }
                else {
                    EditorUtility.DisplayDialog("Response", response.Text, "Ok");
                }
            }));

@TelloViz
Copy link

@jdnichollsc

Thanks for the help btw, here is a progress demo of editor coroutine being used in the way we discussed above.
https://www.youtube.com/watch?v=Kjtuj2zLMKQ Check it out if you want :)

@jdnichollsc
Copy link
Member

@TelloVisionGames wow that's really impressive, thanks for sharing mate and happy new year! 🎉

@jdnichollsc
Copy link
Member

Hello folks, hope you're doing well

Please let me know what you think about this PR: #201

I'm not sure if we need to add that new dependency from package.json file 🤔

Thanks for your collaboration!

@uurha
Copy link

uurha commented Jul 9, 2022

Bump

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants