- Home /
Saving my Equipment Slots
I've been following this small series on YouTube for a few days now. Unfortunately, any comments I make on there do not get answered as the series was made last year and there isn't many people viewing it. However, one big problem I have encountered is saving.
I have two types of inventories, the main inventory and the equipment inventory. When I pick up an item, it goes into the main inventory and the player must drag a specific type of object into an equipment slot to use it. Gas mask goes into the head slot, a ring goes into the hand slot, etc. But when I press the save button, F5, the game saves the inventory, when pressed the button, F6, the game loads the last saved inventory.
Here's my problem. Both the inventory and equipment arrays follow the same code that leads them to the same save path. But it only saves the inventory and only loads the inventory, not the eqipment. No matter what small changes I make, the equipment slots do not want to save. Now this could be because I don't have correct save path, and if that is the case I may need to replicate code to allow both inventories to save in seperate locations. But otherwise, the game just deletes the equipped items from the save entirely.
Here is my code for the Inventory Object, Scriptable Object:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using UnityEditor;
using System.Runtime.Serialization;
[CreateAssetMenu(fileName = "New Inventory", menuName = "Inventory System/Inventory")]
public class InventoryObject : ScriptableObject
{
public string savePath;
public ItemDatabaseObject database;
public Inventory Container;
public GameObject emptyItem;
public Transform player;
public bool AddItem(Item _item, int _amount)
{
if (EmptySlotCount <= 0)
{
return false;
}
InventorySlot slot = FindItemOnInventory(_item);
if (!database.GetItem[_item.id].stackable || slot == null)
{
SetEmptySlot(_item, _amount);
return true;
}
slot.AddAmount(_amount);
return true;
}
public int EmptySlotCount
{
get
{
int counter = 0;
for (int i = 0; i < Container.Items.Length; i++)
{
if (Container.Items[i].item.id <= 1)
{
counter++;
}
}
return counter;
}
}
public InventorySlot FindItemOnInventory(Item _item)
{
for (int i = 0; i < Container.Items.Length; i++)
{
if (Container.Items[i].item.id == _item.id)
{
return Container.Items[i];
}
}
return null;
}
public InventorySlot SetEmptySlot(Item _item, int _amount)
{
for (int i = 0; i < Container.Items.Length; i++)
{
if (Container.Items[i].item.id <= -1)
{
Container.Items[i].UpdateSlot(_item, _amount);
return Container.Items[i];
}
}
//Setup functionality when inventory is full.
return null;
}
public void SwapItems(InventorySlot item1, InventorySlot item2)
{
if (item2.CanPlaceInSlot(item1.ItemObject) && item1.CanPlaceInSlot(item2.ItemObject))
{
InventorySlot temp = new InventorySlot(item2.item, item2.amount);
item2.UpdateSlot(item1.item, item1.amount);
item1.UpdateSlot(temp.item, temp.amount);
}
}
public void RemoveItem(Item _item)
{
for (int i = 0; i < Container.Items.Length; i++)
{
if (Container.Items[i].item == _item)
{
Container.Items[i].UpdateSlot(null, 0);
//Need to drop the item ont the ground.
//Instantiate(emptyItem);
}
}
}
[ContextMenu("Save")]
public void Save()
{
/*string saveData = JsonUtility.ToJson(this, true);
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(string.Concat(Application.persistentDataPath, savePath));
bf.Serialize(file, saveData);
file.Close();*/
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(string.Concat(Application.persistentDataPath, savePath), FileMode.Create, FileAccess.Write);
formatter.Serialize(stream, Container);
stream.Close();
}
[ContextMenu("Load")]
public void Load()
{
if (File.Exists(string.Concat(Application.persistentDataPath, savePath)))
{
/*BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(string.Concat(Application.persistentDataPath, savePath), FileMode.Open);
JsonUtility.FromJsonOverwrite(bf.Deserialize(file).ToString(), this);
file.Close();*/
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(string.Concat(Application.persistentDataPath, savePath), FileMode.Open, FileAccess.Read);
Inventory newContainer = (Inventory)formatter.Deserialize(stream);
for (int i = 0; i < Container.Items.Length; i++)
{
Container.Items[i].UpdateSlot(newContainer.Items[i].item, newContainer.Items[i].amount);
}
stream.Close();
}
}
[ContextMenu("Clear")]
public void Clear()
{
Container.Clear();
}
}
[System.Serializable]
public class Inventory
{
public InventorySlot[] Items = new InventorySlot[10];
public void Clear()
{
for (int i = 0; i < Items.Length; i++)
{
Items[i].RemoveItem();
}
}
}
[System.Serializable]
public class InventorySlot
{
public ItemType[] AllowedItem = new ItemType[0];
[System.NonSerialized]
public UserInterface parent;
public Item item;
public int amount;
public ItemObject ItemObject
{
get
{
if (item.id >= 0)
{
return parent.inventory.database.GetItem[item.id];
}
return null;
}
}
public InventorySlot()
{
item = new Item();
amount = 0;
}
public InventorySlot(Item _item, int _amount)
{
item = _item;
amount = _amount;
}
public void UpdateSlot(Item _item, int _amount)
{
item = _item;
amount = _amount;
}
public void RemoveItem()
{
item = new Item();
amount = 0;
}
public void DropItem(Item _item)
{
}
public void AddAmount(int value)
{
amount += value;
}
public bool CanPlaceInSlot(ItemObject _itemObject)
{
if (AllowedItem.Length <= 0 || _itemObject == null || _itemObject.data.id < 0)
{
return true;
}
for (int i = 0; i < AllowedItem.Length; i++)
{
if (_itemObject.type == AllowedItem[i])
{
return true;
}
}
return false;
}
}
Here is the code for the Player Inventory, MonoBehaviour, this is on the player so they can press the save and load button to save both inventories:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerInventory : MonoBehaviour
{
//public MouseItem mouseItem = new MouseItem();
public InventoryObject inventory;
public InventoryObject equipment;
public bool inventoryOpen = false;
public GameObject inventoryObject;
public void OnTriggerEnter(Collider other)
{
var item = other.GetComponent<GroundItem>();
if (item)
{
Item _item = new Item(item.item);
if (inventory.AddItem(_item, 1))
{
Destroy(other.gameObject);
}
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.F5))
{
inventory.Save();
equipment.Save();
}
if (Input.GetKeyDown(KeyCode.F6))
{
inventory.Load();
equipment.Save();
}
if (Input.GetKeyDown(KeyCode.Tab))
{
inventoryOpen = !inventoryOpen;
ShowHideInventory();
}
}
public void ShowHideInventory()
{
if (inventoryOpen)
{
inventoryObject.SetActive(true);
Cursor.lockState = CursorLockMode.None;
}
else
{
inventoryObject.SetActive(false);
Cursor.lockState = CursorLockMode.Locked;
}
}
private void OnApplicationQuit()
{
inventory.Container.Clear();
equipment.Container.Clear();
}
}
That's it as far as I know, that includes saving. I'll include screenshots for the inspectors for both of my inventory objects. Main Inventory: Equipment Inventory:
Answer by $$anonymous$$ · Mar 02, 2021 at 02:01 AM
private void Update()
{
if (Input.GetKeyDown(KeyCode.F5))
{
inventory.Save();
equipment.Save();
}
if (Input.GetKeyDown(KeyCode.F6))
{
inventory.Load();
equipment.Save(); // should be equipment.Load();
}
if (Input.GetKeyDown(KeyCode.Tab))
{
inventoryOpen = !inventoryOpen;
ShowHideInventory();
}
}
public void ShowHideInventory()
{
if (inventoryOpen)
{
inventoryObject.SetActive(true);
Cursor.lockState = CursorLockMode.None;
}
else
{
inventoryObject.SetActive(false);
Cursor.lockState = CursorLockMode.Locked;
}
}
I must be really tired to have missed that, I'm an idiot. Thanks for pointing it out.