How to load an image from URL with Unity?

后端 未结 6 1781
感情败类
感情败类 2020-12-10 06:05

Please save me from going crazy.

No matter how many times I google, I always end up with (usually deprecated) versions of the following code:

IEnumer         


        
相关标签:
6条回答
  • 2020-12-10 06:35

    You can do that with async/await:

    using System.Threading.Tasks;
    using UnityEngine;
    using UnityEngine.Networking;
    
    public static async Task<Texture2D> GetRemoteTexture ( string url )
    {
        using( UnityWebRequest www = UnityWebRequestTexture.GetTexture( url ) )
        {
            //begin requenst:
            var asyncOp = www.SendWebRequest();
    
            //await until it's done: 
            while( asyncOp.isDone==false )
            {
                await Task.Delay( 1000/30 );//30 hertz
            }
    
            //read results:
            if( www.isNetworkError || www.isHttpError )
            {
                //log error:
                #if DEBUG
                Debug.Log( $"{ www.error }, URL:{ www.url }" );
                #endif
    
                //nothing to return on error:
                return null;
            }
            else
            {
                //return valid results:
                return DownloadHandlerTexture.GetContent( www );
            }
        }
    }
    

    Usage example:

    [SerializeField] string _imageUrl;
    [SerializeField] Material _material;
    Texture2D _texture;
    
    async void Start ()
    {
        _texture = await GetRemoteTexture( _imageUrl );
        _material.mainTexture = _texture;
    }
    
    void OnDestroy () => Dispose();
    public void Dispose () => Object.Destroy( _texture );// memory released, leak otherwise
    
    0 讨论(0)
  • 2020-12-10 06:38

    For Unity 2018+ use UnityWebRequest which replaces the WWW class.

    void Start(){    
        StartCoroutine(DownloadImage(url));
    }
    
    IEnumerator DownloadImage(string MediaUrl)
    {   
        UnityWebRequest request = UnityWebRequestTexture.GetTexture(MediaUrl);
        yield return request.SendWebRequest();
        if(request.isNetworkError || request.isHttpError) 
            Debug.Log(request.error);
        else
            YourRawImage.texture = ((DownloadHandlerTexture) request.downloadHandler).texture;
    } 
    
    0 讨论(0)
  • 2020-12-10 06:38

    Thanks to the question asked by Umair M, I figured out that this method needs to be called using unity's StartCoroutine.

    0 讨论(0)
  • 2020-12-10 06:47
    public void OnStart()
    {
        StartCoroutine(setImage("http://drive.google.com/myimage.jpg")); 
    }
    
    IEnumerator setImage(string url) 
    {
        Texture2D texture = null;
        WWW www = new WWW(url);
        yield return www;
    
        Debug.Log("Why on earh is this never called?");
        texture = WWW.texture;
        //end show Image in texture 2D
    }
    
    0 讨论(0)
  • 2020-12-10 06:50

    quick clarification: https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html

    public void yourMethod()
    {
       StartCoroutine(setImage("http://url/image.jpg")); //balanced parens CAS
    }
    
    IEnumerator setImage(string url) {
        Texture2D texture = profileImage.canvasRenderer.GetMaterial().mainTexture as Texture2D;
    
        WWW www = new WWW(url);
        yield return www;
    
        // calling this function with StartCoroutine solves the problem
        Debug.Log("Why on earh is this never called?");
    
        www.LoadImageIntoTexture(texture);
        www.Dispose();
        www = null;
    }
    
    0 讨论(0)
  • 2020-12-10 06:57

    We can't directly apply texture material on the Image component in the canvas. So, we should create a sprite from the texture downloaded at runtime then apply that sprite in the Image component.

    Try this one,

    IEnumerator DownloadImage(string MediaUrl)
        {   
            UnityWebRequest request = UnityWebRequestTexture.GetTexture(MediaUrl);
            yield return request.SendWebRequest();
            if(request.isNetworkError || request.isHttpError) 
                Debug.Log(request.error);
            else{
                // ImageComponent.texture = ((DownloadHandlerTexture) request.downloadHandler).texture;
    
                Texture2D tex = ((DownloadHandlerTexture) request.downloadHandler).texture;
                Sprite sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(tex.width / 2, tex.height / 2));
                ImageComponent.GetComponent<Image>().overrideSprite = sprite;
            }
        } 
    
    0 讨论(0)
提交回复
热议问题