I was playing around with the inventory system that brackeys displays in one of his YouTube videos which uses scriptable objects for the items. However you can’t save them for obvious reasons, and the only way I could think to make them save is creating a class that simply copies item data but since the actual inventory needs to be saved which is a list of items, how would you go about doing It?
Yes you can:
Look into those, you can create a project bound savable asset. you can also create these at runtime and fill their data in at runtime.
EDIT: look at ScriptableObject.CreateInstance(); for making instances of them.
Make your scriptable object serializable to save it in the inspector when adding it as a field
EDIT2: also when adjusting the data at runtime, note that you are adjusting a saved file so if you change weapon 1 to have an attack damage of 10, it will have that even when you restart the game as it saved this data to the asset file.
EDIT:3 so what i do is have a public reference to the scriptable object that will be the “template” and then a private reference that makes an instance based on the public supplied SO. the private one is called “mutable_” and thats the one I edit, that way the original template data stays as intended and isnt adjusted
Just an idea, but if you can retrieve any inventory by name or number, you can store (that) as well as the inventory location, stack count if relevant, etc…
Hopefully that makes sense.
So this is what I had before I posted
Inventory system script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class InventorySystem : MonoBehaviour {
public List<Item> items = new List<Item>();
public int storageCount = 20;
public static InventorySystem instance;
public delegate void OnItemChanged();
public OnItemChanged onItemChangedCallback;
private void Awake()
{
if(instance != null)
{
Debug.LogWarning("More than one instance of object");
return;
}
instance = this;
}
public bool AddItem(Item item)
{
if(items.Count >= storageCount)
{
Debug.Log("Out of Storage!!");
return false;
}
else
{
items.Add(item);
if(onItemChangedCallback != null)
{
onItemChangedCallback.Invoke();
}
return true;
}
}
public void SubtractItem(Item item)
{
items.Remove(item);
if (onItemChangedCallback != null)
{
onItemChangedCallback.Invoke();
}
}
}
Item ScriptableObject:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Item", menuName = "Inventory Item")]
public class Item : ScriptableObject {
public string itemName;
public string itemDescription;
public string itemRarity;
public Sprite itemSprite;
public int itemPrice;
public int itemSellValue;
}
Okay, was there or a question or were you just sharing? Just curious.
Whoops my question got cut out lol sorry. I was just wondering if just lists where able to be saved and if not then I guess I’ll find some way of making it work with what I got
Well, I am thinking that you want to save what the player has in their inventory, correct?
You do not need to know the price and sell value if you can get the item, if that makes sense?
You don’t seem to have a ‘stack count’ variable, so all you have is that it’s either empty or it’s an item.
If all of your items have unique names, one idea is that you can create a dictionary with each item : string, Item
Then just save the name and the index of the inventory array as 2 members of a class, and maybe the class that you save is a list of the 2 member class? Saving string empty and ‘-1’ for empty items, perhaps.
Does that make sense? I guess what I’m getting at is just save the information that lets you get back the appropriate item, rather than having to save all the data about the item, because that already exists in your scriptable object.
Okay! I’ll try the dictionary idea
Cool, hope it all made sense.