This days I was blocked with a extremely simple task. I wasn’t able to load a multiple sprite in Unity using Resources.Load. Surprisingly there was few or unclear information in the subject so I share a simple solution.
Short solution
Dictionary<string, Sprite> LoadSpriteSheet(string path) { Dictionary<string, Sprite> spriteSheet = new Dictionary<string, Sprite>(); Sprite[] sprites = Resources.LoadAll<Sprite>(path); foreach (Sprite sprite in sprites) { spriteSheet.Add(sprite.name, sprite); } return spriteSheet; }
Explained example
I have a sprite called “deck” in the path “Resources/Sprites/” with the sprite mode set to “Multiple” and I used the sprite editor to generate the subsprites for each card.
As code example I made a MonoBehaviour that shows a random card when you press the key “R”. Tested on Unity 5.5.0 and should work fine on Unity 5.x:
using System.Collections.Generic; using UnityEngine; // be safe... with this you're sure you have an SprteRenderer in the GameObject [RequireComponent(typeof(SpriteRenderer))] public class ShowRandomCard : MonoBehaviour { SpriteRenderer spriteRenderer; Dictionary<string, Sprite> deck; Dictionary<string, Sprite> LoadSpriteSheet(string path) { // a hash container to store the "subsprites" Dictionary<string, Sprite> spriteSheet = new Dictionary<string, Sprite>(); // IMPORTANT: use LoadAll instead Load for "multiple" sprite's type // gets all subsprites in an array Sprite[] sprites = Resources.LoadAll<Sprite>(path); foreach (Sprite sprite in sprites) { // iterate the array and store it in the hash spriteSheet.Add(sprite.name, sprite); } return spriteSheet; } void Awake () { // get the reference of the GameObject's SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>(); // load the deck calling our custom made function deck = LoadSpriteSheet("Sprites/deck"); } void Update () { if (Input.GetKeyDown("r")) { // this generates a string like "1A" meaning rank 1 suite A string cardName = $"{Random.Range(0, 12) + 1}{(char)('A' + Random.Range(0, 4))}"; // get the sprite by name and set the SpriteRenderer with it spriteRenderer.sprite = deck[cardName]; } } }
Expanding your toolset
For all simple and time saving functions like LoadSpriteSheet I never use singletons. They are just simple and independent funtions. Functions, not classes! So the way I organize to access them project wide is using static classes which are like C++ namespaces on steroids.
// Utils.cs example // ... public static class Utils { // ... public static Dictionary<string, Sprite> LoadSpriteSheet(string path) { // ... } }
// SomeBehaviour.cs example void Awake() { Utils.LoadSpriteSheet("deck"); }
Conclusion
Be happy and creative with your beautiful sprite sheets in Unity3d!