Hello everyone,
I have a bug with my inventory system. I have a script (which I’ll include at the end of this post) which places a grid of Slots (which are set to children of SlotPanel) in my SlotPanel GameObject and then it adds Item GameObjects, which are children of the Slot they belong to.
I have changed my computers during development time (I developed this on a PC and now I’m using my laptop). The problem arises when I resize my InventoryPanel (a parent to the SlotPanel, located in my Canvas), my Items don’t display properly (in their Slots), but rather in the middle of their borders or even outside of InventoryPanel.
Although I haven’t resized the Inventory on my PC, I think the problem is with switching development computers. Someone suggested using canvas scaler or anchors (or both) to fix this problem. I also have to fix it because I’m implementing a drag&drop feature in my inventory system and this positioning problem is getting in the way.
Here’s my Inventory.cs code, where Slots and Items get instantiated:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class Inventory : MonoBehaviour
{
GameObject inventoryPanel;
GameObject slotPanel;
ItemDatabase database;
public GameObject inventorySlot;
public GameObject inventoryItem;
int slotAmount;
public List<Item> items = new List<Item>();
public List<GameObject> slots = new List<GameObject>();
//private ItemDatabase itemDatabase;
// Use this for initialization
void Start ()
{
database = GameObject.Find("ItemDatabase").GetComponent<ItemDatabase>();
slotAmount = 32;
inventoryPanel = GameObject.Find("InventoryPanel");
slotPanel = inventoryPanel.transform.FindChild("SlotPanel").gameObject;
for (int i = 0; i < slotAmount; i++)
{
items.Add(new Item());
GameObject slot = Instantiate(inventorySlot);
slot.transform.SetParent(slotPanel.transform);
slot.transform.localPosition = new Vector2(slotPanel.transform.localPosition.x, slotPanel.transform.localPosition.y);
slot.transform.localScale = new Vector2(1, 1);
slots.Add(slot);
}
AddItem(7);
for (int i = 0; i < 10; i++)
{
AddItem(8);
}
AddItem(1);
//itemDatabase = GameObject.FindGameObjectWithTag("ItemDatabase").GetComponent<ItemDatabase>();
}
public void AddItem(int id)
{
Item itemToAdd = database.FetchItemByID(id);
if ((itemToAdd.itemType == Item.ItemType.Stackable) && (CheckIfItemIsInInventory(itemToAdd)))
{
for (int i = 0; i < items.Count; i++)
{
if (items[i].itemID == id)
{
ItemData data = slots[i].transform.GetChild(0).GetComponent<ItemData>();
if (data.amount < itemToAdd.itemStackLimit)
{
data.amount = data.amount + 1;
}
data.transform.GetChild(0).GetComponent<Text>().text = (data.amount).ToString();
break;
}
}
}
else
{
for (int i = 0; i < items.Count; i++)
{
if (items[i].itemID == -1)
{
items[i] = itemToAdd;
Sprite itemSprite = itemToAdd.itemIcon; // NullReferenceException here - not anymore
GameObject itemObjectInstance = Instantiate(inventoryItem);
itemObjectInstance.GetComponent<ItemData>().item = itemToAdd;
//itemObject.GetComponent<SpriteRenderer>().sprite = itemSprite;
//itemObject.GetComponent<SpriteRenderer>().sortingOrder = 1;
//GameObject itemObjectInstance = Instantiate(itemObject);
itemObjectInstance.transform.SetParent(slots[i].transform);
itemObjectInstance.transform.localPosition = new Vector2(slots[i].transform.localPosition.x, slots[i].transform.localPosition.y);
itemObjectInstance.transform.localScale = new Vector2(1, 1);
//itemObjectInstance.GetComponent<SpriteRenderer>().sprite = itemSprite;
// itemObjectInstance.GetComponent<SpriteRenderer>().sortingOrder = 0;
itemObjectInstance.GetComponent<Image>().sprite = itemSprite;
itemObjectInstance.name = itemToAdd.itemName;
//itemObjectInstance.transform.position = slots[i].transform.position;
break;
}
}
}
}
bool CheckIfItemIsInInventory(Item item)
{
for (int i = 0; i < items.Count; i++)
{
if(items[i].itemID == item.itemID)
{
return true;
}
}
return false;
}
}
Do you agree with using the canvas scaler and/or anchors or do you have other ideas? Is my script maybe faulty?
Thanks in advance!
EDIT: I played around with the Canvas Scaler and Anchors and I successfuly prevented Item icons from falling out of their slots, but I’ve got a problem with my drag&drop - I can take the item from a slot and drag it, but when I drop it it changes its position and dissapears into the unknown.
Here’s my script where I handle the drag&drop events:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using System;
public class ItemData : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerDownHandler
{
public Item item;
public int amount;
private Transform _originalParent;
private Vector2 _offset;
public void OnBeginDrag(PointerEventData eventData)
{
if (item != null)
{
// _offset = eventData.position - new Vector2 (this.transform.position.x, this.transform.position.y);
_originalParent = this.transform.parent;
this.transform.SetParent(this.transform.parent.parent);
this.transform.position = eventData.position - _offset;
}
}
public void OnDrag(PointerEventData eventData)
{
if (item != null)
{
this.transform.position = eventData.position - _offset;
}
}
public void OnEndDrag(PointerEventData eventData)
{
this.transform.SetParent(_originalParent);
}
public void OnPointerDown(PointerEventData eventData)
{
if (item != null)
{
_offset = eventData.position - new Vector2(this.transform.position.x, this.transform.position.y);
}
}
}
Any help here? Thanks!