Unity Web Requests: Downloading (and working with) JSON text
Following on from the previous article, let’s take a look at how we can use UnityWebRequest to retrieve some JSON information from an online API. A free (and fun) little API I’ve been introduced to by GameDevHQ, and that’ll work quite nicely for these purposes, is this ‘Cat Facts API’: https://catfact.ninja/.
By typing in something like https://catfact.ninja/fact into your web browser you’ll see the API returns some JSON text, providing in this case a ‘fact’ and some information about the length of the fact. With then help of UnityWebRequest, we can use this URL in Unity and display a random cat fact to the player every time they press the spacebar for instance 😉
As we did previously, create a new script (something like ‘DownloadText’) and add in the ‘using UnityEngine.Networking’ statement. Then create a serialised private string variable for a URL and a serialised private Text or TextMeshProUGUI variable for component we’ll display the text onto (you’ll also need ‘using UnityEngine.UI’ or ‘using TMPro’ respectively).
Next, we’ll need to create a ‘GetText’ coroutine to handle the retrieval of the JSON data. First we’ll need to declare and initialise a new UnityWebRequest variable, assigning to it ‘UnityWebRequest.Get([URL string variable])’. We’ll then call the UnityWebRequest.SendWebRequest() method on this variable, as well as yield return/wait for it to finish in the same statement:
Next, we’ll need to check whether there’s been a HTTP error or a Network error and Debug.LogError an error message to the console. If there hasn’t been an error, then the text should now be available for us to store in a variable. We can create a new string variable called something like ‘text’ (or just a generic ‘var’ variable) and assign ‘UnityWebRequest.downloadHandler.text’ to it:
We’re now onto something I found particularly nifty — converting JSON data into a C# class. In order to do this, we’re first going to need the JSON ‘model’, which we can either turn into a class ourselves or try to get an online convertor to do it for us. Back on the Cat Facts API website, open up the ‘Fact’ dropdown and scroll down to the ‘Responses’ section. You should find something like this:
Copy the content of that code snippet and paste it into the left JSON side of the JSON to C# Class convertor, then click on Convert:
As you can see, it’s outputted a class called ‘Root’ based on that JSON data, and given it a string variable to store the ‘fact’ and an integer variable to store the ‘length’ information from the JSON data.
Back in our Unity script, we can paste in this Root class, rename it to something like ‘Fact’, and then probably do away with the default getters and setters on the variable. That should give us something like this:
With this set up, we can now create a Fact variable in our code and assign to it ‘JsonUtility.FromJson<Fact>(text)’. The JSON utility class and method will attempt to convert the JSON text we’ve received from our web request into the class we just created. Since we made this class using a JSON conver’fator (and we’re only using some fairly basic string and int variables), we shouldn’t run into many issues with this.
Finally, we can now set our Text.text or TextMeshProUGUI.text to our Fact variable’s ‘fact’ member variable. This should then display the fact itself to our UI element, leaving out the information we’re not currently interested in such as the fact’s length. Head back into Unity, let it compile, set up your UI, fill out any of the public/serialised private variables on the script, head into Play mode, and you should have something that looks and works like this:
Hope this was helpful! I think this was the first time I’ve actually knowingly set up a C# class in Unity to map JSON data onto. I’ll include the finished DownloadText class below in case it’d be of use 😉