I'm trying to adapt my current inventory so that the items can occupy more than one slots (cells) like in this image:
Any idea that might help me? My inventory is an Image that has grid layout and inside it, there's other images (which represents the slots), and each slot has the object "Image" inside which is the sprite of the item:
Items:
[CreateAssetMenu(fileName = "New Item", menuName = "Create new Item")]
[System.Serializable]
public class Items : ScriptableObject
{
public int id;
public string itemName;
public GameObject prefab;
public Sprite icon;
public int maxStack = 1;
}
I tried to define in class item an line
height
and a list
of type sprite
in my icon
but don't know how it would fit with the rest of the code.
ItemObject
is a class that represents the object instantiated in the game:
public class ItemObject : MonoBehaviour
{
public Items itemStats;
public int amount;
}
Slot the behaviour of each individual slot and when I try to drag an item into it:
public class Slot : MonoBehaviour, IDropHandler
{
public Items ItemInSlot;
public int AmountInSlot =1;
Image icon;
Image panel;
TextMeshProUGUI txt_amount;
public void SetStats()
{
transform.GetChild(0).gameObject.SetActive(true);
icon = GetComponentInChildren<Image>();
panel = icon.GetComponentInChildren<Image>();
txt_amount = panel.GetComponentInChildren<TextMeshProUGUI>();
if (ItemInSlot == null)
{
transform.GetChild(0).gameObject.SetActive(false);
return;
}
icon.sprite = ItemInSlot.icon ;
txt_amount.text = $"{AmountInSlot}x";
}
public void OnDrop(PointerEventData eventData)
{
GameObject dropped = eventData.pointerDrag; // image being dragged
InventoryUIInteraction draggableItem = dropped.GetComponent<InventoryUIInteraction>();
Slot slot = draggableItem.draggedItemParent.GetComponent<Slot>();
if (slot == this)
return;
if (ItemInSlot != null && ItemInSlot.id != slot.ItemInSlot.id)
return;
if (ItemInSlot)
{
if (ItemInSlot.maxStack == AmountInSlot)
return;
if (ItemInSlot.maxStack < (AmountInSlot + slot.AmountInSlot))
{
int remainingAmount = (AmountInSlot + slot.AmountInSlot) - ItemInSlot.maxStack;
AmountInSlot = ItemInSlot.maxStack;
slot.AmountInSlot = remainingAmount;
SetStats();
}
else
{
AmountInSlot += slot.AmountInSlot;
slot.ItemInSlot = null;
slot.AmountInSlot = 0;
SetStats();
}
}
else
{
ItemInSlot = slot.ItemInSlot;
AmountInSlot = slot.AmountInSlot;
slot.ItemInSlot = null;
slot.AmountInSlot = 0;
SetStats();
}
}
}
And the Inventory class that handles the logic of an item being picked and placing it:
public class InventorySystem : MonoBehaviour
{
[SerializeField] public Slot[] slots = new Slot[40];
[SerializeField] GameObject InventoryUI;
private void Awake()
{
for (int i = 0; i < slots.Length; i++)
{
if (slots[i].ItemInSlot == null)
{
slots[i].transform.GetChild(0).gameObject.SetActive(false);
}
}
}
private void Update()
{
if (!InventoryUI.activeInHierarchy && Input.GetKeyDown(KeyCode.E))
{
InventoryUI.SetActive(true);
}
else if (InventoryUI.activeInHierarchy && Input.GetKeyDown(KeyCode.E) || Input.GetKeyDown(KeyCode.Escape))
{
InventoryUI.SetActive(false);
}
}
public void PickUpItem(ItemObject obj)
{
int remainingAmount = obj.amount;
// Check if the item can be stacked in existing slots or added to empty slots
for (int i = 0; i < slots.Length; i++)
{
if (slots[i].ItemInSlot != null)
{
if (slots[i].ItemInSlot.id == obj.itemStats.id && slots[i].AmountInSlot < slots[i].ItemInSlot.maxStack)
{
int remainingSpace = slots[i].ItemInSlot.maxStack - slots[i].AmountInSlot;
int amountToAdd = Mathf.Min(remainingAmount, remainingSpace);
slots[i].AmountInSlot += amountToAdd;
remainingAmount -= amountToAdd;
slots[i].SetStats();
if (remainingAmount == 0)
{
// All items have been added to existing slots
Destroy(obj.gameObject);
return;
}
}
}
else
{
slots[i].ItemInSlot = obj.itemStats;
slots[i].AmountInSlot = Mathf.Min(remainingAmount, slots[i].ItemInSlot.maxStack);
remainingAmount -= slots[i].AmountInSlot;
slots[i].SetStats();
if (remainingAmount == 0)
{
// All items have been added to empty slots
Destroy(obj.gameObject);
return;
}
}
}
// If there are still remaining items, they don't fit in the inventory
obj.amount = remainingAmount;
}
}
Any guidance would be extremally helpful.