Monday, February 29, 2016

Unity: Load image in sprite, from resource and from file

I cannot waste the opportunity to post something in Feb 29th :), so I will go a little technical and share something I did recently in a Unity project.

If you want to load an image in a sprite programmatically, one way is to have your image file in a folder called Resources. This is to load an image file (i.e. PNG, JPEG, etc), not a prefab or anything like that.

If not already there, create Resources folder inside your Assets folder, Unity knows it is an special folder. So let's say you imported you image AwesomeImage.png into that folder. Now in your scene create a sprite: GameObject > 2D Object > Sprite (in Unity 5.2). Then you can create a C# script like this and add it to your sprite.

public class YourSpriteScript : MonoBehaviour {

    void Start()
    {
        ShowIcon("AwesomeImage");
    }

    void ShowIcon(string imageName)
    {
        TextAsset asset = Resources.Load(imageName) as TextAsset;
        byte[] data = asset.bytes;
        Texture2D texture = new Texture2D(128, 128, TextureFormat.ARGB32, false);
        texture.LoadImage(data);
        texture.name = imageName;
        Sprite icon = Sprite.Create(texture, new Rect(0.0f, 0.0f, texture.width, texture.height), new Vector2(0.5f, 0.5f));

        SpriteRenderer iconRenderer = GetComponent<SpriteRenderer>();
        iconRenderer.sprite = icon;
    }
}

In some special cases you may want to load an image which is outside your Unity project, you normally would want this if you want the final user to change set any image she wants into your game. There are of course other ways to do it, this is only one of them that could work for cases like those when you want to allow others to make mods of your game by replacing some images.

To do it, use the following code, it will load the image from disk. So, again, this is the C# script you could add to an specific sprite:

public class YourSpriteScript : MonoBehaviour {

    public void ShowIcon(string iconPath)
    {
        byte[] data = File.ReadAllBytes(iconPath);
        Texture2D texture = new Texture2D(128, 128, TextureFormat.ARGB32, false);
        texture.LoadImage(data);
        texture.name = Path.GetFileNameWithoutExtension(iconPath);
        Sprite icon = Sprite.Create(texture, new Rect(0.0f, 0.0f, texture.width, texture.height), new Vector2(0.5f, 0.5f));

        SpriteRenderer iconRenderer = GetComponent<SpriteRenderer>();
        iconRenderer.sprite = icon;
    }
}

As you may see, the code is very similar, once you get the bytes from the image you create a Texture2D from it and use it to create a Sprite object which is set as the sprite of your Unity sprite (actually, a SpriteRenderer).

Consider that better than set this script in each sprite you could modify it to make a more generic version that receives a reference to the sprite and the name of the file to load, and have one single script that is called to load multiple sprites. Also you will need to investigate how to use relative paths so the game works in any computer.

Hope this helps in whatever you are tying to create! Let me know if you need additional help.

No comments:

Post a Comment