Download Images From a Url Endpoint in Runtime with Unity
Tags: unity3d, tutorial, gamedev
Published: 2019-12-06 21:50:56

In this tutorial, we will make a GET HTTP method to download an image and use it in the scene. I'll use this 600x600 [image](https://via.placeholder.com/600/92c952) from [JSONPlaceholder](https://jsonplaceholder.typicode.com/) .

First, making a client. Create a script `Client`. 

```c#
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Client : MonoBehaviour
{
	IEnumerator GetTextureRequest(string url)
    {
        using(var www = UnityWebRequestTexture.GetTexture(url))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.Log(www.error);
            }
            else
            {
                if (www.isDone)
                {
                  //handle the result
                }
            }
        }
      }
}
```

To make a GET request we need to use `UnityEngine.Networking` namespace. But, our goal is specifically downloading an image in runtime, unity has some useful api to handle this work. Remaining work is easy, making a sprite from this downloaded texture. Further info on `DownloadHandlerTexture` [here](https://docs.unity3d.com/ScriptReference/Networking.DownloadHandlerTexture.html).

```c#
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Client : MonoBehaviour
{
	IEnumerator GetTextureRequest(string url, System.Action<Sprite> callback)
    {
        using(var www = UnityWebRequestTexture.GetTexture(url))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.Log(www.error);
            }
            else
            {
                if (www.isDone)
                {
		            var texture = DownloadHandlerTexture.GetContent(www);
                    var rect = new Rect(0, 0, 600f, 600f);
                    var sprite = Sprite.Create(texture,rect,new Vector2(0.5f,0.5f));
                    callback(sprite);
                }
            }
        }
      }
}
```

I've added a second parameter to the method, because since unity coroutines can't return a type, I'll use an `Action` as a callback here. 

To make a sprite, `Sprite` class provides a `Create` method that takes a `Texture2D` argument as the source of sprite, a `Rect` argument to configure dimensions and a `Vector2` to define pivot point for the sprite.

To make it visible on the screen, I need a Sprite object in the scene and a reference it's `SpriteRenderer` to pass downloaded sprite.

To complete the `Client` let's call the coroutine in `Start`.

```c#
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Client : MonoBehaviour
{
    public SpriteRenderer spriteRenderer;
    
    private Sprite targetSprite;
    private string url = "https://via.placeholder.com/600/92c952";

    private void Start() 
    {
        StartCoroutine(GetTextureRequest(url, (response) => {
            targetSprite = response;
            spriteRenderer.sprite = targetSprite;
        })); 
    }   

	IEnumerator GetTextureRequest(string url, System.Action<Sprite> callback)
    {
        using(var www = UnityWebRequestTexture.GetTexture(url))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.Log(www.error);
            }
            else
            {
                if (www.isDone)
                {
					var texture = DownloadHandlerTexture.GetContent(www);
                    var rect = new Rect(0, 0, 600f, 600f);
                    var sprite = Sprite.Create(texture,rect,new Vector2(0.5f,0.5f));
                    callback(sprite);
                }
            }
        }
      }
}
```



Now, I need some objects in the scene. 

Create a Sprite in Hierarchy.

![sc1](https://thepracticaldev.s3.amazonaws.com/i/97nfz3ms016mr36150sg.png)

Next, create another object for Client and make sure that referencing Sprite object's renderer to Client.

![sc2](https://thepracticaldev.s3.amazonaws.com/i/badq8s7r2rbsqzf43n1m.png)

Now it's good to go. Hit to play!

![gif](https://thepracticaldev.s3.amazonaws.com/i/pnnugdro4ru4ldia6vp9.gif)

Consider that, it may consume some processing power for multiple files. Here is my profiler result for this single image: 

![sc3](https://thepracticaldev.s3.amazonaws.com/i/q7xcodoob5vownjhnmpf.png)