Hey all! I just wanted to show off the inventory system that I’ve been working on for the past week now. I would really like it if you could give me any feedback, or suggest any feature that would make it even better. But anyways, here’s how it works.
First, I created a Scriptable Item Item:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[CreateAssetMenu]
public class Item : ScriptableObject
{
public string ItemName;
public enum ItemRarity {Common, Epic, Legendary, GodTier};
public ItemRarity itemRarity;
public float Damage;
public float Range;
public float NumberOfBulletsAbleToBeHeld;
public Sprite ItemIcon;
public GameObject gameObject;
}
Then I created another script referencing this. (To put on other game objects)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PhysicalItem : MonoBehaviour
{
public Item item;
}
I attached an image of my Canvas hierarchy(which is important because the code for organizing the inventory kind of relies on knowing where the children of each slot reside and their order on the hierarchy).
I also created a prefab Slot, which consists of an image and text box (which will be for displaying ammo when I get around to implementing it). This prefab will be instantiated on the panel element that the player has selected and the image will change based on the item the player picks up. I also attached the PhysicalItem script to the slot prefab so we can always know which gun belongs to which slot.
Anyways, the code for the inventory is below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class Inventory : MonoBehaviour
{
public float numberOfSlotSelected = 1;
public Transform selectedPanel;
Transform availablePanel;
public GameObject slot;
public List<Item> inventory;
public Image select;
public TMP_Text selectedGunText;
public List<Transform> availableSlots;
public List<Transform> possibleSlots;
public List<Transform> closestAvailablePanel;
// Start is called before the first frame update
void Start()
{
numberOfSlotSelected = 1;
inventory = new List<Item>();
availableSlots = new List<Transform>();
closestAvailablePanel = new List<Transform>();
int i = transform.childCount;
while(i > 0)
{
if(transform.GetChild(i - 1).childCount == 0)
{
possibleSlots.Add(transform.GetChild(i - 1)); //becuase child index starts at 0
}
i--;
}
}
// Update is called once per frame
void Update()
{
int numberOfSlotSelected_Int = (int)numberOfSlotSelected;
numberOfSlotSelected += Input.mouseScrollDelta.y;
selectedPanel = transform.GetChild(numberOfSlotSelected_Int - 1); //We use -1 because unity starts egtting children at 0. So the first child would be child 0 not child 1
if (numberOfSlotSelected > 5)
{
numberOfSlotSelected = 1;
}
if (numberOfSlotSelected < 1)
{
numberOfSlotSelected = 5;
}
//=======================================================================================================================================================================================//
//DETERMINE WHICH PANEL IS OPEN
closestAvailablePanel.Clear();
foreach (Transform available in availableSlots)
{
if (Vector3.Distance(selectedPanel.position, available.position) <= 100 && available.childCount == 0)
{
closestAvailablePanel.Add(available);
}
}
if (selectedPanel.childCount == 0)
{
availablePanel = selectedPanel;
}
if (selectedPanel.childCount >= 1)
{
if (closestAvailablePanel.Count >= 1)
{
availablePanel = closestAvailablePanel[0];
}
//THIS IS BASICALLY FOR IF YOU KEEP YOUR CURSOR ON THE FIRST SLOT THE WHOLE TIME WHILE PICKING UP ITEMS
if(availableSlots.Count > 0 && selectedPanel != possibleSlots[0])
{
if (transform.GetChild(numberOfSlotSelected_Int).childCount >= 1)
{
closestAvailablePanel.Clear();
foreach (Transform available in availableSlots)
{
availablePanel = availableSlots[availableSlots.Count - 1];
}
}
}
//THIS IS BASICALLY FOR IF YOU KEEP YOUR CURSOR ON THE LAST SLOT THE WHOLE TIME WHILE PICKING UP ITEMS
if(availableSlots.Count > 0 && selectedPanel == possibleSlots[0])
{
if (transform.GetChild(numberOfSlotSelected_Int - 2).childCount >= 1)
{
closestAvailablePanel.Clear();
foreach (Transform available in availableSlots)
{
availablePanel = availableSlots[availableSlots.Count - 1];
}
}
}
}
//THIS IS FOR WHEN THERE IS ONLY ONE SLOT LEFT
if (availableSlots.Count == 1)
{
availablePanel = availableSlots[0];
}
//=======================================================================================================================================================================================//
select.transform.position = selectedPanel.position;
//SHOW SELECTED ITEM'S NAME
if (selectedPanel.childCount >= 1)
{
selectedGunText.text = selectedPanel.GetComponentInChildren<PhysicalItem>().item.ItemName;
}
else if(selectedPanel.childCount == 0)
{
selectedGunText.text = "";
}
}
public void Add(Item pickedUpItem)
{
GameObject instantiatedSlot = Instantiate(slot, availablePanel.position, Quaternion.identity);
instantiatedSlot.transform.SetParent(availablePanel);
instantiatedSlot.transform.GetChild(0).GetComponent<TMP_Text>();
instantiatedSlot.transform.GetChild(1).GetComponent<Image>().sprite = pickedUpItem.ItemIcon;
instantiatedSlot.GetComponent<PhysicalItem>().item = pickedUpItem;
availableSlots.Clear();
foreach (Transform available in possibleSlots)
{
if (available.childCount == 0)
{
availableSlots.Add(available);
}
}
}
}
And the code for picking up the game objects is in my player controller script:
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Item"))
{
if(GameObject.Find("Inventory").GetComponent<Inventory>().inventory.Count < 5)
{
GameObject.Find("Inventory").GetComponent<Inventory>().inventory.Add(other.gameObject.GetComponent<PhysicalItem>().item);
GameObject.Find("Inventory").GetComponent<Inventory>().Add(other.gameObject.GetComponent<PhysicalItem>().item);
Destroy(other.gameObject);
}
}
}
Again, I just made this in a week, and currently, I have no way to drop items, but I’m still developing it and wil post updates here if anyone is interested.
Again, I would really appreciate any feedback you might have.
Thanks!