Your SO actually has a UUID so that you can save a reference to it in InventoryItem. In each of the stores (Inventory, ActionBar, Equipment, ItemDropper) you have the SaveableEntity. These are the objects responsible for saving the reference to SO so that you can capture/restore their existence.
In the SO itself, you don’t need a SaveableEntity (that won’t even make sense), but you can implement the ISaveable interface with them…
In the backing stores, you’ll need to save a bit more than the ID… you’ll also need to run CaptureState on the ScriptableObject you’re saving and get it’s information.
I added CaptureState/RestoreState to InventoryItem, but I made them abstract, so that each of the things that overrides them must implement their own CaptureState/RestoreState as override.
Then in the structures for saving in each of the stores, I added a public object state
Here’s an example in Inventory:
[System.Serializeable]
private struct InventorySlotRecord
{
public string itemID;
public int number;
public object state;
}
object ISaveable.CaptureState()
{
var slotStrings = new InventorySlotRecord[inventorySize];
for (int i = 0; i < inventorySize; i++)
{
if (slots[i].item != null)
{
slotStrings[i].itemID = slots[i].item.GetItemID();
slotStrings[i].number = slots[i].number;
slotStrings[i].state = slots[i].item.CaptureState();
}
}
return slotStrings;
}
void ISaveable.RestoreState(object state)
{
var slotStrings = (InventorySlotRecord[])state;
for (int i = 0; i < inventorySize; i++)
{
slots[i].item = Instantiate(InventoryItem.GetFromID(slotStrings[i].itemID));
slots[i].number = slotStrings[i].number;
slots[i].item.RestoreState(slotStrings[i].state;
}
if (inventoryUpdated != null)
{
inventoryUpdated();
}
}