So… I’m currently prototyping a collectible card game thingy, and I might be a little bit stuck.
My core issue is how to handle card assets and decks in regard to saving and loading them. So, basically, how should I design my data structures and interact with the Unity Asset Pipeline.
At the base level, I currently have a script called Card, and each card is a Prefab with this script attached. Then, I have a class Deck, that looks like this (abridged and mostly irrelevant to the problem):
public class Deck
{
public GameObject[] cardsInDeck;
public string name = "TestDeck";
[System.NonSerialized]
private List<GameObject> library;
// check if deck is valid
public bool Validate() { /* [...] */ }
// shuffle deck
public void Start()
{
GameObject[] currentDeck = new GameObject[cardsInDeck.Length];
foreach(GameObject card in cardsInDeck)
{
while (true)
{
//put the card in a random slot of the deck
int position = Mathf.FloorToInt(Random.Range(0, cardsInDeck.Length));
if (position == cardsInDeck.Length) continue;
if(currentDeck[position] == null)
{
currentDeck[position] = card;
break;
}
}
}
library = new List<GameObject>(currentDeck);
}
public GameObject DrawCard()
{
if(library.Count == 0)
{
// deck is used up!
return null;
}
int position = Mathf.FloorToInt(Random.Range(0, library.Count));
if (position == library.Count) position--;
GameObject result = library[position];
library.RemoveAt(position);
return result;
}
}
Meaning: I have a bunch of references to the prefabs in cardsInDeck, which is edited in the deck editor and can be saved and loaded. When an actual game of cards is started, library is seeded with a shuffled copy of cardsInDeck (still only references to prefabs). Only when a card is actually drawn, an actual GameObject is added to the scene graph (and that happens outside of this script).
And then, for the deck editor, I have a class called CardManager that contains nothing but a List of the prefabs for all cards that exist. Currently, the deck editor instantiates these prefabs when a card is added to the deck, and that instance is then added to the deck.
PROBLEM: I do not want any actual card data in my deck save files, because that causes a whole bunch of problems whenever I change cards. So I need some kind of identifier for the prefab that I can save to the file and then use upon loading to retrieve the associated prefab.
QUESTIONS: How do I get such a unique identifier? One that keeps working when I change cards, or add new ones? Is there any possibility to go back from this identifier to the actual prefab through the Asset Pipeline? Or should I use an entirely different approach for loading card graphics and data, e.g. through the Resources folder?
I mean, I could probably just use the index of a card in the CardManager’s card list, but that seems horribly, horribly half-assed and will break if I ever remove a card from the list… so I really don’t want to use that route.
Any pointers?