An instance of a ScriptableObject definition is data that you can reference everywhere. In your case, such an instance could represent a card in your game. How you organize these instances, that is up to you and your need in the game.
What you could do, for example, is creating a SO instance for every card in your game and if the player has a collection of cards, appropriately reference them there. Note that SO instances alone usually do not solve everything, often you need wrappers. If a player has collected a card, for instance, such a simple wrapper could look like this:
public class CardCollection : MonoBehaviour {
[Serializable]
public class CollectedCard {
public Card instance; // Card : ScriptableObject
public int amount;
}
[SerializeField]
private CollectedCard[] collected;
}
In other words, ScriptableObjects are a good start, but you will usually need to build around them, not just with a simple list or array, but complex structures, containers and wrappers.
I not really sure about how to find and add my SO in my class.
Now I have 1 prefab (a card) and several SO that change attribute of my card.
Edit: I make a struct that store all my cards generated:
When I use Class rather than Struct it doesn´t work, i don´t know why? → “NullReferenceException: Object reference not set to an instance of an object” on these lines:
[/i]* any idea? - Is it a good start? What can I improve? ```csharp *public class Deck : MonoBehaviour
{
[Serializable]
public struct PlayerDeck
{
public GameObject Cards; // Card : ScriptableObject
public int amount;
}
public PlayerDeck playerDeck;
/***** Prefab card *****/
public GameObject prefabCard;
public SoCards tmpSoCards;
public string results;
public GameObject initCard;
/***** Parent *****/
public GameObject cardsList;
public void Start()
{
prefabCard = GameObject.FindGameObjectWithTag(“Prefab Card”);
cardsList = GameObject.FindGameObjectWithTag(“Cards List”); // Game object that will contain all Cards (Game object)
/***** Init Deck *****/
results = AssetDatabase.FindAssets("t:SoCards"); // Path of cards SO
tmpSoCards = new SoCards[results.Length]; //store the path
playerDeck = new PlayerDeck[results.Length]; //Struct with all cards
for (int i = 0; i < results.Length; i++)
{
tmpSoCards[i] = (SoCards)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(results[i]), typeof(SoCards));
initCard = Instantiate(prefabCard);
initCard.transform.SetParent(cardsList.transform);
initCard.name = AssetDatabase.GUIDToAssetPath(results[i]);
initCard.GetComponentInChildren<CardsEffects>().data = tmpSoCards[i];
initCard.SetActive(false);
playerDeck[i].Cards = initCard;
playerDeck[i].amount = 1;
}
A class reference can either reference an instanced object or nothing, whereas a struct always references an instanced object. In other words, if you have a class reference, you have to assign an instanced object to it before using it while when using a struct, you get the default object of that struct type.
To use it as a class, add this to your code:
playerDeck = new PlayerDeck[results.Length]
for(int someIndex = 0; someIndex < playerDeck; someIndex++){
playerDeck[someIndex] = new PlayerDeck();
}