Adding actions to a scriptable object

Hi,

I have a scriptable object for an item and would like to add possible actions for the item when you right click it. Ideally, I would ike to add a list of abilities to the scriptable object but don’t know how I can serialize it to add them through the Inspector :frowning: Also starting to think I’m going in the wrong direction completely.

Does anyone have any tips how to go about this? Another thought I had was to add all of the abilities to a dicitionary and reference the key on the scriptable object but not sure how to go about that at the moment.

Scriptable object:

[CreateAssetMenu(fileName = "ItemPickable", menuName = "Data/Items/ItemPickable")]
public class ItemPickableData : ScriptableObject
{
    public string description;

    public Sprite floorSprite;
    public Vector2 floorSize;

    public Sprite inventorySprite;
    public Vector2Int inventorySize;

    public Sprite storedSprite;
    public Vector2 storedSize;
}

I have created an abstract class for Ability:

public abstract class Ability<T>
{
    public abstract void Do();
}

And would like to add abilities such as:

public class Drop : Ability<GameObject>
{
    public override void Do()
    {
        // Do
    }
}

public class Eat : Ability<GameObject>
{
    public override void Do()
    {
        // Do
    }
}

public class Dig : Ability<GameObject>
{
    public override void Do()
    {
        // Do
    }
}

Adding the abilities to a dictionary and referencing them works but it feels a bit wrong and seems like it could easily mess up.

public static class AbilityList
{
    public static readonly Dictionary<int, Ability> abilities = new Dictionary<int, Ability>()
    {
        { 0, new PickUp() },
        { 1, new Drop() },
        { 2, new Dig() }
    };
}
[CreateAssetMenu(fileName = "ItemPickable", menuName = "Data/Items/ItemPickable")]
public class ItemPickableData : ScriptableObject
{
    public string description;

    public Sprite floorSprite;
    public Vector2 floorSize;

    public Sprite inventorySprite;
    public Vector2Int inventorySize;

    public Sprite storedSprite;
    public Vector2 storedSize;

    public List<int> itemActions = new List<int>();
}
public void OnClick()
        {
            Debug.Log("Clicked on " + data.description);

            foreach (int i in data.itemActions)
            {
                bool _bool = AbilityList.abilities.TryGetValue(i, out Ability ability);
                ability.Do();
            }
        }

You can make the Ability a scriptableobject too, then reference it in a list on the item.

1 Like

I’m not sure I get what you mean. Like this?

[CreateAssetMenu(fileName = "Eat Action", menuName = "Data/Actions/Eat")]
public class Eat : ScriptableObject
{
    public void Do()
    {
        // Do
        Debug.Log("Eat Up");
    }
}

[CreateAssetMenu(fileName = "Use Action", menuName = "Data/Actions/Use")]
public class Use : ScriptableObject
{
    public void Do()
    {
        // Do
        Debug.Log("Use");
    }
}

These no longer have the same Abillity base class, so I could reference it as a scriptableObject list but unsure how to call the function, as each one could have different functions. Sorry if I’m missing something and thanks for the help :slight_smile:

Ah, I see what you mean now! I found this link:

Thanks for the help!