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 from JSONPlaceholder .
First, making a client. Create a script Client
.
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.
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
.
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.
Next, create another object for Client and make sure that referencing Sprite object's renderer to Client.
Now it's good to go. Hit to play!
Consider that, it may consume some processing power for multiple files. Here is my profiler result for this single image:
Top comments (2)
Your tutorial is great i think it might just save me from a problem i am having.
But i am unable to save the sprite in an array.
Here is the problematic code:
i am doing a foreach loop with an array of links from which i intend to get my sprites, but instead of assigning it inmediatly to a SpriteRenderer i save it in an array of the same size.
The two problems i have are that, 1. Its only saving the last sprite in 'collectableUrls', and 2. 'i' the index in which it should save the sprite array ' collectables' is the length of the array, while it should be one less than the length to prevent IndexOutOfBounds.
I am terribly confused, i want to use this as a generic method because this one method, i think, it should work for a generic string[] i give it and i should be able to save it in a generic sprite[], since i have to get several sprites with different pourpuses.
I got a brute force solution but i dont like it and i rather use a more elegant, shorter and generic code, instead of one IEnumerator coroutine for each array.
if you could point me into a direction it would mean a lot.
Thanks in advance and sorry for the long answer.
in case you send a different url to an image file as you should verify that