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);
}
}
Answer by Mouton · Sep 26, 2019 at 10:35 PM
You could achieve your goal with UnityEvents (https://docs.unity3d.com/ScriptReference/Events.UnityEvent.html).
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<T0>) 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);
}
}
Thanks for the response! I was looking at UnityEvent and it seems that is derives from $$anonymous$$onobehaviour. Wouldn't that make it incompatible with ScriptableObject? If it doesn't I guess I missed something.
UnityEvents derives from UnityEventBase which is an abstract root class, it doesn't inherit $$anonymous$$onoBehaviour.
It would not be a problem since effects
is an attribute of the Item
class, it will store reference to UnityEvents.
I'm not sure why, but when I tried to implement it wasn't showing it in the inspector. But I just put what you suggested again and it worked! I'm not sure what I did wrong the last time. Thanks so much for the help, this feels like setting it up this way will make it scalable.