3
\$\begingroup\$

I know that Asset Bundles exist, and I'm already taking a look at them. But I'm still interested in this particular approach:


I am interested in downloading a .png image from the Web, and then "consolidate" it as a Sprite asset. After doing so, I can display this sprite in my game in the future without ever downloading that image again.

I was able to download the image and use its texture to create a Sprite object and use it for my SpriteRenderer:

        WWW request = new WWW("www.example.com/image.png");
        yield return request;
        if (request.isDone) {
            ((SpriteRenderer)renderer).sprite = Sprite.Create(request.texture, new Rect(0,0,request.texture.width,request.texture.height), new Vector2(0.5f,0.5f));
        }

Is it possible to grab this texture and generate a Sprite asset? With all the properties like pivot, pixels per unit, packing tag, etc?


UPDATE

Alright, so turns out that Sprite.Create let's me set the pivot and pixels to units properties. No packing tag, though, but I guess that makes sense since packing should be done during development and not during runtime.

Given this, I suppose one could serialize the generated Sprite class.

\$\endgroup\$
1
  • \$\begingroup\$ Download and store it in the application persistent data path for later access \$\endgroup\$
    – Sata
    Dec 20, 2015 at 23:35

3 Answers 3

2
\$\begingroup\$

I wrote some code to handling this in my current project

public IEnumerator getImageFromWS(string fileName, Action<Texture2D> result = null){
    var path = Application.persistentDataPath+"/"+PathToFile+"filename"+".png";

    var f = new FileInfo(path);
    if(f.Exists)
    {
        var retVal = new Texture2D(0,0, TextureFormat.RGBA32, false);
        retVal.LoadImage(File.ReadAllBytes(path));
        if(result != null)
            result(retVal);
    }else{
        var WWW = new WWW("www.example.com/image.png");
        if (!www.isDone || !string.IsNullOrEmpty (www.error)) {
            Debug.LogError ("Load fail : " + url);
            if (result != null)
                result (null);
            yield break;
        }

        Save (www.texture.EncodeToPNG (), path);

        if (result != null)
            result (www.texture);
    }
}

The Save method refer to this :

public static void Save (byte[] data, string path)
{
    var file = new FileInfo (path);
    file.Directory.Create ();

    File.WriteAllBytes (path, data);

    data = null;
}

With an extending method that take a Texture2D and return a Sprite

public static Sprite ToSprite (this Texture2D t, Vector2? v = null)
{
    var vector = v ?? new Vector2(.5f, .5f);
    return Sprite.Create(t, new Rect(0, 0, t.width, t.height), vector);
}

And you can call this like :

StartCoroutine (getImageFromWS ("image",
        texture => SpriteToLoad.GetComponent<Image> ().sprite = texture.ToSprite ()));

Hoping that this will be useful

\$\endgroup\$
5
  • \$\begingroup\$ and what about "Save" class? \$\endgroup\$ Dec 27, 2017 at 13:16
  • \$\begingroup\$ ty a lot! Have error on ToSprite on vector before ??(have to declare it). Can you advice me how to fix it? \$\endgroup\$ Dec 27, 2017 at 14:29
  • \$\begingroup\$ Sorry, I've totally lost all my Unity skills, can you send me details about error ? \$\endgroup\$
    – Sata
    Dec 27, 2017 at 14:36
  • \$\begingroup\$ joxi.ru/GrqlMzocND94OA \$\endgroup\$ Dec 27, 2017 at 14:41
  • \$\begingroup\$ I've edited the ToSprite method implementation, hope it fix your error \$\endgroup\$
    – Sata
    Dec 27, 2017 at 14:44
1
\$\begingroup\$

You could do something like this:

public GameObject Gameobj;

Gameobj.GetComponent<SpriteRenderer>().sprite = 
  Sprite.Create(
    www.texture, 
    new Rect( 0, 0, www.texture.width, www.texture.height ), 
    new Vector2( 0.5f, 0.5f ) );
\$\endgroup\$
0
\$\begingroup\$

The way you are doing it is more or less the only way you can do it without sticking it into your build or into an asset bundle. There is a call for WWW that will auto-cache it for you, WWW.LoadFromCacheOrDownload, but it only works with asset bundles, so you could make a single texture asset bundle and cache it that way. If that's not an option, you'll have to create your own caching mechanism

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .