How to access and change scriptable objects on instantiated prefabs

Hi, been stuck on this for the last ten hours and going slightly mad.

So trying to create a deck of cards. I made this work in version 1 by creating a bunch of prefabs which were just images. One per card type (e.g. “Strike”). The card had a name, cost, picture and description, but they were just a single flat image. If I wanted to change the card had to be redo the picture. Single script with public gameobject variables for each card type, linked in the editor to matching prefab. A list to store the deck and a loop to instantiate the deck into a card space area [that’s all I wanted to do at this stage]. Would use conditional logic later to check the card name and determine appropriate damage, apply effects etc. All worked fine, but limited… so…

Onto scriptable objects… I’ve scaled back a little, so I have an image with frames and a space just for title and description (I’ll add more if I can make this work). Added title and description text fields to image (show as child objects in the hierarchy), created a prefab from it. Then setup scriptable objects with name and description and created those from the assets menu. Have three scripts which I’ll attach below. It works, kind of but I have to drag a specific scriptable object onto the prefab. What I wanted was…

I wanted to be able to have just a single prefab, instantiate it and then be able to specify which scriptable object to load to populate it on the screen. So my first question (of two) is is that possible? or should I create multiple prefabs for each card type like before with different scriptable objects attached… or something else?

Second question (sorry there’s two) is how to then access that information elsewhere. So, even if I have one prefab for each card. if I instantiate a “Strike” and it has scriptableobject property of description or a mana cost, how could I access that from any script. My previous method of using a List of card names and checking the name + conditional logic won’t work.

I hope that’s not a dumb question, I’m still learning. Ok, here’s the code, its limited with no actual deck, just producing a single card presently. If anyone can help I would be very appreciative. I have spent ten hours trying to find answers and reading a range of different options, none of which really cover what I’m trying to do.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


// Script to create new scriptable objects
[CreateAssetMenu(fileName = "New Card", menuName = "New Card")]
public class Card : ScriptableObject
{
    public string cardtitle;
    public string description;
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

//script attached to the prefab
public class CardDisplay : MonoBehaviour
{
    public Card Card;
    public Text cardname;
    public Text descriptiontext;
   
    public void LoadCardData(ScriptableObject CardData)
    {
        cardname.text = Card.cardtitle;
        descriptiontext.text = Card.description;
        
    }
}  

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

// script attached to empty game objects
public class GameController : MonoBehaviour
{
    // Linked the prefab here
    public GameObject BaseCard;
    // Area filling the canvas with grid layout
    public GameObject CardArea;
    public ScriptableObject CardData;

    void Start()
    {
        GameObject PlayerCard = Instantiate(BaseCard, new Vector3(0, 0,0), Quaternion.identity) as GameObject;
        // Call LoadCardData from the CardDisplay script to populate the text fields
        PlayerCard.GetComponent<CardDisplay>().LoadCardData(CardData);
        PlayerCard.transform.SetParent(CardArea.transform, false);
    }

}

You can use this

[CreateAssetMenu(fileName = "New Card", menuName = "New Card")]
public class Card : ScriptableObject {
	public string cardtitle;
	public string description;
}