Let's suppose a classic card game, designed in Unity (say the latest release as of now, so 2018.2.16). Visible cards are
SpriteRenderers (probably a
Card prefab). One or several script objects are responsible of instantiating card objects as required, and inform each card of its current value; the card then does whatever is needed to display the correct image. Now, here is the twist: we would like to offer alternate sets of images for the cards (let say 10 designs); these alternate images would be included in the application itself (that is, on-demand content is outside the scope of this question).
Stating the obvious
This is clearly a case for spritesheets. So at design time, pictures of each card of a set (52 regular faces, 2 jokers and card's back) are layout in a single image file (that is, one image file per card-set design). So we have 10 spritesheets, each containing 55 sprites, and only one spritesheet (and therefore only one version of each of those 55 sprites) is to be in use at any given time. We want to avoid having unused images in RAM and/or on the GPU. Therefore, only the currently selected spritesheet should actually be loaded.
So the question is: how to efficiently load, manage and use sprites in such situation?
My first intuition would be to go for something along the line of
Resources.loadAll<Sprite>("CardSets/CardSetName"). That is, each card set would be split in 55 sprites, stored in a directory specific to that card set. However, many sources, including some official documentation from Unity, discuss
Resources as an old and undesirable subsystem, and recommend moving away from it. So let's consider other options...
Suppose I am very patient and would not bother manually linking (or scripting in the editor...) every single sprites of every card sets, that is all 55 * 10 sprites, to some GameObject(s) inside the editor... Would it be reasonable? Would spritesheets for non-selected card sets be loaded in RAM and/or on GPU from the moment we open the scene, or only the spritesheet of the currently selected spritesheet? What if each card set is associated with a specific prefab instead, and I only instantiate the prefab corresponding to the currently selected card set?
Alternatively, assuming that all spritesheets is packed using exactly the same layout, would it be possible/make sense to reuse the sprite objects themselves, and instead swap their texture image? Would that be any better? How would one get access to these textures without having all textures be preloaded at scene creation, and yet avoid
At last, what about sprite atlas? They seem a very good candidate for this problem, but the same questions goes as for texture replacements: how would one get access to these textures without having all textures be preloaded at scene creation, and yet avoid
And there might also be other strategies I am not aware of...
Now, this is a lot of subquestions, and I don't expect answers to all of these. Simply put, what would be a correct and efficient strategy to load, manage and use sprites in this example situation, based on current Unity's technology?
Note 1: I know that this question is similar to How can I dynamically load the correct sprite from a sprite sheet? . I however think that is is significantly different in that 1) Unity's technology has evolved a lot since 2014 (official recommendations are now to avoid
Resources.LoadAll(), and Sprite Atlas have been recently added) and 2) that other question considered only one card set, so it doesn't posed the extra issue of reducing memory usage.
Note 2: I am not really making a card game; this is only an example that make it easier to explain and present the core concepts that I want to clarify here (that is, proper strategies regarding management of alternate spritesheets). Please do not suggest that I draw text labels instead of having several sprites, that is not an applicable solution.