I have implimented an inventory system in my game that allows me to pick up spawned objects, through scriptable objects, and I can click and drag them, equip them, drop them back into the world etc.
The major headache comes with saving and loading these things into another scene. So if I pick up an object in one scene, then move into another, that object should still be in my inventory. I paid for Easy Save 3 as I was having such difficulty but I'm getting to that point of development where it's easy to be overwhelmed and feel like i'm only making matters worse.
Any help would be greatly appreciated, or even pointing in the right direction.
Thank you, please see below my Inventory script. This is attached to the player character. There are seperte scripts for Inventory SlotUI, and InventoryUI attached to the canvas.
Code: Select all
/// <summary>
/// Provides storage for the player inventory. A configurable number of
/// slots are available.
///
/// This component should be placed on the GameObject tagged "Player".
/// </summary>
public class Inventory : MonoBehaviour, ISaveable
{
// CONFIG DATA
[Tooltip("Allowed size")]
[SerializeField] int inventorySize = 16;
// STATE
InventorySlot[] slots;
public struct InventorySlot
{
public InventoryItem item;
public int number;
}
// PUBLIC
[Tooltip("Typically leave unticked so temporary Dialogue Managers don't unregister your functions.")]
public bool unregisterOnDisable = false;
/// <summary>
/// Broadcasts when the items in the slots are added/removed.
/// </summary>
public event Action inventoryUpdated;
/// <summary>
/// Convenience for getting the player's inventory.
/// </summary>
public static Inventory GetPlayerInventory()
{
var player = GameObject.FindWithTag("Player");
return player.GetComponent<Inventory>();
}
/// <summary>
/// Could this item fit anywhere in the inventory?
/// </summary>
public bool HasSpaceFor(InventoryItem item)
{
return FindSlot(item) >= 0;
}
/// <summary>
/// How many slots are in the inventory?
/// </summary>
public int GetSize()
{
return slots.Length;
}
/// <summary>
/// Attempt to add the items to the first available slot.
/// </summary>
/// <param name="item">The item to add.</param>
/// <param name="number">The number to add.</param>
/// <returns>Whether or not the item could be added.</returns>
public bool AddToFirstEmptySlot(InventoryItem item, int number)
{
int i = FindSlot(item);
if (i < 0)
{
return false;
}
slots[i].item = item;
slots[i].number += number;
print(slots[i].number);
if (inventoryUpdated != null)
{
inventoryUpdated();
}
return true;
}
/// <summary>
/// Is there an instance of the item in the inventory?
/// </summary>
public bool HasItem(InventoryItem item)
{
for (int i = 0; i < slots.Length; i++)
{
if (object.ReferenceEquals(slots[i].item, item))
{
return true;
}
}
return false;
}
public bool HasItemID(string itemID)
{
//if (slots[0].item == null) return false;
for (int i = 0; i < slots.Length; i++)
{
if (slots[i].item != null)
{
if (slots[i].item.GetItemID() == itemID)
{
return true;
}
}
}
return false;
}
/// <summary>
/// Return the item type in the given slot.
/// </summary>
public InventoryItem GetItemInSlot(int slot)
{
return slots[slot].item;
}
/// <summary>
/// Get the number of items in the given slot.
/// </summary>
public int GetNumberInSlot(int slot)
{
return slots[slot].number;
}
/// <summary>
/// Remove a number of items from the given slot. Will never remove more
/// that there are.
/// </summary>
public void RemoveFromSlot(int slot, int number)
{
slots[slot].number -= number;
if (slots[slot].number <= 0)
{
slots[slot].number = 0;
slots[slot].item = null;
}
if (inventoryUpdated != null)
{
inventoryUpdated();
}
}
public void RemoveWithID(string itemID, double number)
{
for (int i = 0; i < slots.Length; i++)
{
if (slots[i].item != null)
{
if (slots[i].item.GetItemID() == itemID)
{
RemoveFromSlot(i, Convert.ToInt32(number));
return;
}
}
}
//slots[slot].number -= number;
//if (slots[slot].number <= 0)
//{
// slots[slot].number = 0;
// slots[slot].item = null;
//}
//if (inventoryUpdated != null)
//{
// inventoryUpdated();
//}
}
/// <summary>
/// Will add an item to the given slot if possible. If there is already
/// a stack of this type, it will add to the existing stack. Otherwise,
/// it will be added to the first empty slot.
/// </summary>
/// <param name="slot">The slot to attempt to add to.</param>
/// <param name="item">The item type to add.</param>
/// <param name="number">The number of items to add.</param>
/// <returns>True if the item was added anywhere in the inventory.</returns>
public bool AddItemToSlot(int slot, InventoryItem item, int number)
{
if (slots[slot].item != null)
{
return AddToFirstEmptySlot(item, number); ;
}
var i = FindStack(item);
if (i >= 0)
{
slot = i;
}
slots[slot].item = item;
slots[slot].number += number;
if (inventoryUpdated != null)
{
inventoryUpdated();
}
return true;
}
// PRIVATE
private void Awake()
{
slots = new InventorySlot[inventorySize];
}
/// <summary>
/// Find a slot that can accomodate the given item.
/// </summary>
/// <returns>-1 if no slot is found.</returns>
private int FindSlot(InventoryItem item)
{
int i = FindStack(item);
if (i < 0)
{
i = FindEmptySlot();
}
return i;
}
/// <summary>
/// Find an empty slot.
/// </summary>
/// <returns>-1 if all slots are full.</returns>
private int FindEmptySlot()
{
for (int i = 0; i < slots.Length; i++)
{
if (slots[i].item == null)
{
return i;
}
}
return -1;
}
/// <summary>
/// Find an existing stack of this item type.
/// </summary>
/// <returns>-1 if no stack exists or if the item is not stackable.</returns>
private int FindStack(InventoryItem item)
{
if (!item.IsStackable())
{
return -1;
}
for (int i = 0; i < slots.Length; i++)
{
if (object.ReferenceEquals(slots[i].item, item))
{
return i;
}
}
return -1;
}
[System.Serializable]
private struct InventorySlotRecord
{
public string itemID;
public int number;
}