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\$
  • \$\begingroup\$ Download and store it in the application persistent data path for later access \$\endgroup\$ – Sata Dec 20 '15 at 23:35
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\$
  • \$\begingroup\$ and what about "Save" class? \$\endgroup\$ – GuardFromUA Dec 27 '17 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\$ – GuardFromUA Dec 27 '17 at 14:29
  • \$\begingroup\$ Sorry, I've totally lost all my Unity skills, can you send me details about error ? \$\endgroup\$ – Sata Dec 27 '17 at 14:36
  • \$\begingroup\$ joxi.ru/GrqlMzocND94OA \$\endgroup\$ – GuardFromUA Dec 27 '17 at 14:41
  • \$\begingroup\$ I've edited the ToSprite method implementation, hope it fix your error \$\endgroup\$ – Sata Dec 27 '17 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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.