Using scriptableobjects as consumable items?

Currently I’m using a scriptableobject class “Item” to allow me to easily make new items and modify attributes they may have. I also have an inventory that I can easily add items and everything I have is working correctly. The problem I’m running into is that I want to override the Use() method so I can have different effects for each item. What is the best way to go about this? Having to reference a gameobject with a script for a particular item doesn’t seem desirable, since you would have to have a gameobject for each item, and my inventory is a list of Items and doesn’t store gameobjects. Any advice would be appreciated.

[CreateAssetMenu(fileName = “New Item”, menuName = “Inventory/Item”)]

public class Item : ScriptableObject

{
new public string name = “New Item”;

public string description = "Item Description";
public bool isDefaultItem = false;

public virtual void Use()
{
    //Use the item
    //Something might happen

    Debug.Log("Using " + name);
    RemoveFromInventory();
}

public void RemoveFromInventory()
{
    Inventory.instance.Remove(this);
}

}

You could achieve your goal with UnityEvents (Unity - Scripting API: UnityEvent).

Add a UnityEvent effects field to your class Item , then in the inspector you can define the different effects you require.

public class Item : ScriptableObject
{
    public string name;
    public string description;
    public bool isDefaultItem;
    public UnityEvent effects;
         
    public virtual void Use(){
        if (effects != null)
            effects.Invoke();
    }
}

To define your effects, you can store them in a single class ItemEffects.

public static class ItemEffects
{
    public static RestoreHealth()
    {
    }

    public static SetDebuff()
    {
    }
}

You can also pass arguments to your effects with the generic version of Unity events (UnityEvent) and pass it a struct or a class.

public class Item : ScriptableObject
{
    public UnityEvent<MyParams> effects;
         
    public virtual void Use(MyParams params){
        if (effects != null)
            effects.Invoke(params);
    }
}