Reputation: 37596
I'm trying to load an image from url to GameObject.
I found the next tutorial:
https://www.youtube.com/watch?v=8UK2EsKBzv8
The download succeeded, but I can't see the image.
What am I doing wrong?
// Use this for initialization
void Start () {
StartCoroutine(loadSpriteImageFromUrl("https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/408px-Google_2015_logo.svg.png"));
}
IEnumerator loadSpriteImageFromUrl(string URL)
{
// Check internet connection
if (Application.internetReachability == NetworkReachability.NotReachable)
{
yield return null;
}
var www = new WWW(URL);
Debug.Log("Download image on progress");
yield return www;
if (string.IsNullOrEmpty(www.text))
{
Debug.Log("Download failed");
}
else
{
Debug.Log("Download succes");
Texture2D texture = new Texture2D(1, 1);
www.LoadImageIntoTexture(texture);
Sprite sprite = Sprite.Create(texture,
new Rect(0, 0, texture.width, texture.height),
Vector2.one / 2);
GetComponent<SpriteRenderer>().sprite = sprite; // Change current sprite
}
}
EDIT
After moving as suggested from ScriptRenderer to UI Image, the code looks like this:
IEnumerator loadSpriteImageFromUrl(string URL, GameObject cell)
{
// Check internet connection
if(Application.internetReachability == NetworkReachability.NotReachable)
{
yield return null;
}
var www = new WWW(URL);
Debug.Log("Download image on progress");
yield return www;
if(string.IsNullOrEmpty(www.text))
{
Debug.Log("Download failed");
}
else
{
Debug.Log("Download succes");
Texture2D texture = new Texture2D(1, 1);
www.LoadImageIntoTexture(texture);
Sprite sprite = Sprite.Create(texture,
new Rect(0,0, texture.width, texture.height),
Vector2.one/2);
cell.AddComponent<Image>();
cell.GetComponent<Image>().sprite = sprite;
}
}
But I'm getting next result to the screen (and not the image in the url):
Upvotes: 3
Views: 12499
Reputation: 1
Thanks Programmer for the detailed answer! I just wanted to add an async version based on Programmer's snippets in case you don't want to work with coroutines
public async Task<Sprite> GetSpriteFromURL(string url)
{
UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
UnityWebRequestAsyncOperation task = www.SendWebRequest();
while (!task.isDone) await Task.Yield();
if (www.result == UnityWebRequest.Result.ProtocolError || www.result == UnityWebRequest.Result.ConnectionError)
{
throw new System.Exception("Error while Receiving: " + www.error);
}
else
{
Debug.Log("Success");
Texture2D tex = DownloadHandlerTexture.GetContent(www);
return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
}
}
Usage:
public async Task<Sprite> GetImageForX(string example)
{
if (example == "A")
return await GetSpriteFromURL(URL1);
else
return await GetSpriteFromURL(URL2);
}
Upvotes: 0
Reputation: 125455
Your code is fine. The downloaded Image is not showing because you are in the Scene-View and the camera is away from it.
Select the GameObject the script is attached to then press F. It should zoom into it and you will see the downloaded image. See here for how to reset your Unity layout to get the Game-View back.
If you still can't see the image then the SpriteRenderer
is not in front of the camera. From the screenshot, its position is 0
,0
,0
so make sure that the camera's position is 0
,0
,-10
.
The right Way to Display Image:
To simply display image in Unity, use the Image
or RawImage
component. RawImage
is recommended since it doesn't generate garbage when changing the Texture. You should already know how to di this from th
If you need to attach Rigidbody or 2D Colliders to that Image then use SpriteRenderer
or MeshRenderer
for 3D Objects to display the image
.
These are the four ways to display an image in Unity. #2 is recommended if no physics or collision is needed at-all:
1.With the Image
Component:
public Image imageToDisplay;
string url = "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/408px-Google_2015_logo.svg.png";
void Start()
{
StartCoroutine(loadSpriteImageFromUrl(url));
}
IEnumerator loadSpriteImageFromUrl(string URL)
{
WWW www = new WWW(URL);
while (!www.isDone)
{
Debug.Log("Download image on progress" + www.progress);
yield return null;
}
if (!string.IsNullOrEmpty(www.error))
{
Debug.Log("Download failed");
}
else
{
Debug.Log("Download succes");
Texture2D texture = new Texture2D(1, 1);
www.LoadImageIntoTexture(texture);
Sprite sprite = Sprite.Create(texture,
new Rect(0, 0, texture.width, texture.height), Vector2.zero);
imageToDisplay.sprite = sprite;
}
}
There have been problems with LoadImageIntoTexture
in the past. For this reason, my other examples won't use LoadImageIntoTexture
. If you see a question mark as the Image then use www.bytes
with the Texture2D.LoadImage
function.
Simply replace:
Texture2D texture = new Texture2D(1, 1);
www.LoadImageIntoTexture(texture);
with
Texture2D texture = new Texture2D(1, 1);
texture.LoadImage(www.bytes);
texture.Apply();
2.With the RawImage
Component(Recommended):
public RawImage imageToDisplay;
string url = "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/408px-Google_2015_logo.svg.png";
void Start()
{
StartCoroutine(loadSpriteImageFromUrl(url));
}
IEnumerator loadSpriteImageFromUrl(string URL)
{
WWW www = new WWW(URL);
while (!www.isDone)
{
Debug.Log("Download image on progress" + www.progress);
yield return null;
}
if (!string.IsNullOrEmpty(www.error))
{
Debug.Log("Download failed");
}
else
{
Debug.Log("Download succes");
Texture2D texture = new Texture2D(1, 1);
texture.LoadImage(www.bytes);
texture.Apply();
imageToDisplay.texture = texture;
}
}
3.With the SpriteRenderer
Component:
Mostly used for 2D Objects and 2D physics simulation with Rigidbody2D and 2D Colliders. If not then use the UI(#1 or #2) above.
public SpriteRenderer imageToDisplay;
string url = "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/408px-Google_2015_logo.svg.png";
void Start()
{
StartCoroutine(loadSpriteImageFromUrl(url));
}
IEnumerator loadSpriteImageFromUrl(string URL)
{
WWW www = new WWW(URL);
while (!www.isDone)
{
Debug.Log("Download image on progress" + www.progress);
yield return null;
}
if (!string.IsNullOrEmpty(www.error))
{
Debug.Log("Download failed");
}
else
{
Debug.Log("Download succes");
Texture2D texture = new Texture2D(1, 1);
www.LoadImageIntoTexture(texture);
Sprite sprite = Sprite.Create(texture,
new Rect(0, 0, texture.width, texture.height), Vector2.zero);
imageToDisplay.sprite = sprite;
}
}
4.With the MeshRenderer
Component:
Mostly used for 3D Objects and 3D physics simulation with Rigidbody and 2D Colliders. If not then use the UI(#1 or #2) above. Just a use a Plane, Quad or a Cube with a MeshRenderer
.
public MeshRenderer imageToDisplay;
string url = "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/408px-Google_2015_logo.svg.png";
void Start()
{
StartCoroutine(loadSpriteImageFromUrl(url));
}
IEnumerator loadSpriteImageFromUrl(string URL)
{
WWW www = new WWW(URL);
while (!www.isDone)
{
Debug.Log("Download image on progress" + www.progress);
yield return null;
}
if (!string.IsNullOrEmpty(www.error))
{
Debug.Log("Download failed");
}
else
{
Debug.Log("Download succes");
Texture2D texture = new Texture2D(1, 1);
www.LoadImageIntoTexture(texture);
imageToDisplay.material.mainTexture = texture;
}
}
New Unity version:
The WWW
API seems to be deprecated now. UnityWebRequest
should now be used.
public Image imageToUpdate;
void Start()
{
StartCoroutine(downloadImage());
}
IEnumerator downloadImage()
{
string url = "http://wallpaper-gallery.net/images/hq-images-wallpapers/hq-images-wallpapers-12.jpg";
UnityWebRequest www = UnityWebRequest.Get(url);
DownloadHandler handle = www.downloadHandler;
//Send Request and wait
yield return www.SendWebRequest();
if (www.isHttpError || www.isNetworkError)
{
UnityEngine.Debug.Log("Error while Receiving: " + www.error);
}
else
{
UnityEngine.Debug.Log("Success");
//Load Image
Texture2D texture2d = new Texture2D(8, 8);
Sprite sprite = null;
if (texture2d.LoadImage(handle.data))
{
sprite = Sprite.Create(texture2d, new Rect(0, 0, texture2d.width, texture2d.height), Vector2.zero);
}
if (sprite != null)
{
imageToUpdate.sprite = sprite;
}
}
}
You can also use the UnityWebRequestTexture.GetTexture
and DownloadHandlerTexture.GetContent
function to download, process and get the image faster.
IEnumerator downloadImage()
{
string url = "http://wallpaper-gallery.net/images/hq-images-wallpapers/hq-images-wallpapers-12.jpg";
UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
DownloadHandler handle = www.downloadHandler;
//Send Request and wait
yield return www.SendWebRequest();
if (www.isHttpError || www.isNetworkError)
{
UnityEngine.Debug.Log("Error while Receiving: " + www.error);
}
else
{
UnityEngine.Debug.Log("Success");
//Load Image
Texture2D texture2d = DownloadHandlerTexture.GetContent(www);
Sprite sprite = null;
sprite = Sprite.Create(texture2d, new Rect(0, 0, texture2d.width, texture2d.height), Vector2.zero);
if (sprite != null)
{
imageToUpdate.sprite = sprite;
}
}
}
Upvotes: 8