I’m making a simple card game. It doesn’t use a standard deck, but that doesn’t matter to the question… pretend I am, so it’s easier to get what I’m talking about.
Rather than making 52 separate card images, it makes sense to put them all in a single atlas, like what you’d do for a spritesheet, then chop them up within Unity using the Sprite Editor, and name the frames e.g. 2c, 3c, 4c… Kc, Ac, 2d, 3d, 4d… etc.
My question is then simply how I set the “frame” to the appropriate card at runtime. I.e. I instantiate a card from the prefab and then want a function in my script that I can call like:
SetCard(“Jc”);
To change the card’s texture to the right one for the Jack of Clubs. Surely this is possible and easy… I just don’t know what function to call, or even what component I need to call it on. Obviously, I could just set up a 52-state animation controller with 52 different one-frame animations, but that is a lot of tedious work and also obviously a stupid kludge.
You should have a card prefab. It may basically consist of a sprite renderer. You should create a cardScript and add the script to spriterenderer as a component. You do it by dragging the script on to sprite renderers components.
So when you create a card from prefab, you can reach your script by getcomponent And Simply call e method that sets spriterenderers sprite.
In your script the method could be something like this:
myRenderer.sprite = Resources.Load("cards",Sprite) as Sprite;
That works, and applies the image of the first card in the deck (“cards” is the spritesheet as a whole). However, trying to set a specific card like:
myRenderer.sprite = Resources.Load("Jd",Sprite) as Sprite;
Does nothing. Doesn’t even throw an error. Also tried the following, neither of which worked.
myRenderer.sprite = Resources.Load("cards/Jd",Sprite) as Sprite;
myRenderer.sprite = Resources.Load("cards.Jd",Sprite) as Sprite;
I guess I’ll just have to do it the stupid way and either bring the cards in as 52 (well, 28 for my custom deck) separate graphic resources and make a single object that loads the appropriate one.
Aha! Figured it out. The answer is Resources.LoadAll instead of Resources.Load and store them in an array, then set them by index:
var sprites : Array;
var rndr: SpriteRenderer;
function Start () {
sprites = Resources.LoadAll("cards",Sprite);
rndr = gameObject.AddComponent("SpriteRenderer");
SetCard(1,11);
}
function SetCard(suit:int,rank:int) {
rndr.sprite = sprites[suit*13+rank];
}
That would give you the King of Diamonds, for instance (assuming you have the cards laid out as Clubs, Diamonds, Hearts, Spades, and with the Ace at the end of the row after the King and not at the start).