0
\$\begingroup\$

I'm extremely new to Unity, and I'm trying to figure out if this design makes sense. I'm creating a card game in which multiple instances of the same card will exist. I'm trying to determine if the "idiomatic" way to do this is as follows:

  • Create a Scriptable Object to contain card metadata.
  • Then create specific Scriptable Objects for each card.
  • Then at runtime, whenever I need a specific card, I create a gameObject add the (simple for example purposes) IsCard MonoBehavior and associate IsCard with whatever ScriptableObject corresponds to the specific card in question to extract/assign metadata.

Does this make sense or is there a more performant/idiomatic way to do this?

This is my current implementation of the above solution.

using UnityEngine;
using UnityEngine.UI;
 
 
[CreateAssetMenu(fileName = "CardSO", menuName = "ScriptableObjects/Card")]
public class CardSO : ScriptableObject
{
    public string cardName;
    public Image cardImage;
    // There could be more specific SOs for creatures, spells, etc.
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
[RequireComponent(typeof(Image))]
public class IsCard : MonoBehaviour
{
 
    public CardSO cardSO;
 
    // Start is called before the first frame update
    void Start()
    {
        if (cardSO == null)
        {
            return;
        }
 
        Image image = GetComponent<Image>();
        image.sprite = cardSO.cardImage.sprite;
        //Reference/Utilize other properties when applicable.
        //If this were a creature, perhaps we could have a mono behavior that stores power/toughness, etc.
        //public int power;
        //power = creatureCardSO.power;
    }
}
```
\$\endgroup\$
4
  • 1
    \$\begingroup\$ This looks reasonable to me, though you could save yourself a runtime search for the image component by caching it at edit time. Have you encountered any particular issues with this approach that we can help you solve? Or are there any specific concerns you project will be important later, based on your modelling? (You may also find the past Q&A in the "Related" section at the right informative) \$\endgroup\$
    – DMGregory
    Commented Jan 13, 2023 at 1:38
  • \$\begingroup\$ Ok, I can tell the difference between the editor association, runtime association, and edit time association. I didn't realize that edit time was "a thing." That's useful, thank you. That being said, based on what you just said, I think I figured out something. Given that I'll have the cards at compile time, there isn't really a reason to programmatically associate the sprite with an image, since I can just create a Prefab (through the editor) with the Image and Scriptable object, then at runtime, I can fetch that prefab when required, right? \$\endgroup\$
    – Steve P.
    Commented Jan 13, 2023 at 2:16
  • \$\begingroup\$ It sounds like you have a plan — how does it work when you try it? \$\endgroup\$
    – DMGregory
    Commented Jan 13, 2023 at 3:21
  • \$\begingroup\$ Yeah, I'm good. Thanks. \$\endgroup\$
    – Steve P.
    Commented Jan 13, 2023 at 4:13

1 Answer 1

2
\$\begingroup\$

Yes, this is a perfectly viable approach.

But another approach you could consider is to represent card types not as ScriptableObjects but as prefabs. The advantage is that prefab instances can be changed. So when you want to have mechanics in the game which modify individual cards that are already on the table, then you can change the data of the card instance directly without changing the data for all other instances of the card. When you are working with scriptable objects, then you would need a rather complicated system on the cards for managing instant-specific modifiers to the card attributes inherited from the scriptable object.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .