Forum begins after the advertisement:
[Part 9] Moving the inventory item bug
Home › Forums › Video Game Tutorial Series › Creating a Farming RPG in Unity › [Part 9] Moving the inventory item bug
- This topic has 16 replies, 4 voices, and was last updated 11 months, 2 weeks ago by Terence.
-
AuthorPosts
-
October 11, 2023 at 6:59 pm #12069::
Hello, i’m doing part 9 of the farming RPG and i stumble upon this bug. When i tried to equip tools and item, the tools and item didn’t equip in the hand.
here are my InventoryManager
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class InventoryManager : MonoBehaviour { public static InventoryManager Instance { get; private set; } private void Awake() { if (Instance != null && Instance != this) { Destroy(this); } else { Instance = this; } } [Header("Tools")] [SerializeField] private ItemSlotData[] toolSlots = new ItemSlotData[10]; [SerializeField] private ItemSlotData toolEquiptSlot = null; [Header("Items")] [SerializeField] private ItemSlotData[] itemSlots = new ItemSlotData[10]; [SerializeField] private ItemSlotData itemEquiptSlot = null; public Transform handPoint; public void InventoryToHand(int indexSlot, InvSlots.TipeInventory tipeInventory) { ItemSlotData handEquip = toolEquiptSlot; ItemSlotData[] inventoryAlter = toolSlots; if(tipeInventory == InvSlots.TipeInventory.Item) { handEquip = itemEquiptSlot; inventoryAlter = itemSlots; } if (handEquip.Stackable(inventoryAlter[indexSlot])) { ItemSlotData slotAlter = inventoryAlter[indexSlot]; handEquip.AddQuantity(slotAlter.quantity); slotAlter.Empty(); } else { ItemSlotData slotToEquipt = new ItemSlotData(inventoryAlter[indexSlot]); inventoryAlter[indexSlot] = new ItemSlotData(handEquip); EquipHandSlot(slotToEquipt); } if(tipeInventory == InvSlots.TipeInventory.Item) { RenderHand(); } UIManager.Instance.RenderInventory(); } public void HandToInventory(InvSlots.TipeInventory tipeInventory) { ItemSlotData handSlot = toolEquiptSlot; ItemSlotData[] inventoryAlter = toolSlots; if(tipeInventory == InvSlots.TipeInventory.Item) { handSlot = itemEquiptSlot; inventoryAlter = itemSlots; } if(!StackItemToInv(handSlot, inventoryAlter)) { for (int i = 0; i < inventoryAlter.Length; i++) { if (inventoryAlter[i].IsEmpty()) { inventoryAlter[i] = new ItemSlotData(handSlot); handSlot.Empty(); break; } } } if(tipeInventory == InvSlots.TipeInventory.Item) { RenderHand(); } UIManager.Instance.RenderInventory(); } public bool StackItemToInv(ItemSlotData itemSlot, ItemSlotData[] invArray) { for(int i = 0; i < invArray.Length; i++) { if (invArray[i].Stackable(itemSlot)) { invArray[i].AddQuantity(itemSlot.quantity); itemSlot.Empty(); return true; } } return false; } public void RenderHand() { if (handPoint.childCount > 0) { Destroy(handPoint.GetChild(0).gameObject); } if (SlotEquipped(InvSlots.TipeInventory.Item)) { Instantiate(GetEquippedSlotItem(InvSlots.TipeInventory.Item).gameModel, handPoint); } } #region Gets and Checks public DataItem GetEquippedSlotItem(InvSlots.TipeInventory tipeInventory) { if (tipeInventory == InvSlots.TipeInventory.Item) { return itemEquiptSlot.itemData; } return toolEquiptSlot.itemData; } public ItemSlotData GetEquippedSlot(InvSlots.TipeInventory tipeInventory) { if (tipeInventory == InvSlots.TipeInventory.Item) { return itemEquiptSlot; } return toolEquiptSlot; } public ItemSlotData[] GetInventorySlot(InvSlots.TipeInventory tipeInventory) { if (tipeInventory == InvSlots.TipeInventory.Item) { return itemSlots; } return toolSlots; } public bool SlotEquipped(InvSlots.TipeInventory tipeInventory) { if (tipeInventory == InvSlots.TipeInventory.Item) { return !itemEquiptSlot.IsEmpty(); } return !toolEquiptSlot.IsEmpty(); } public bool IsTool(DataItem item) { EquipmentData equipment = item as EquipmentData; if (equipment != null) { return true; } DataSeed seed = item as DataSeed; return seed != null; } #endregion public void EquipHandSlot(DataItem item) { if (IsTool(item)) { toolEquiptSlot = new ItemSlotData(item); } else { itemEquiptSlot = new ItemSlotData(item); } } public void EquipHandSlot(ItemSlotData itemSlot) { DataItem item = itemSlot.itemData; if (IsTool(item)) { toolEquiptSlot = new ItemSlotData(itemSlot); } else { itemEquiptSlot = new ItemSlotData(itemSlot); } } #region Validating Inventory private void OnValidate() { //validasi slot tangan ValidateInventorySlot(toolEquiptSlot); ValidateInventorySlot(itemEquiptSlot); //validasi slot inventaris ValidateInventorySlots(itemSlots); ValidateInventorySlots(toolSlots); } void ValidateInventorySlot(ItemSlotData slot) { if (slot.itemData != null && slot.quantity == 0) { slot.quantity = 1; } } void ValidateInventorySlots(ItemSlotData[] array) { foreach (ItemSlotData slot in array) { ValidateInventorySlot(slot); } } #endregion // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } }
October 13, 2023 at 5:45 am #12075::Hi Sand Man,
Your code looks correct, so the issue may lie in InvSlots, UIManager or with the configuration of the components in the Inspector.
- Ensure that the SlotIndexes are assigned correctly in UIManager
- Ensure that the Hand Slots are configured correctly
- InvSlots Display function is working as intended
October 13, 2023 at 5:55 pm #12076::Hi Jonathan,
thanks for replying. I found out the bug was my stackable bool only has one equal and not two on my ItemSlotData script.
January 2, 2024 at 7:10 pm #12865::Sand Man Can you send me a picture of the error position? I have a same problem with you
January 2, 2024 at 7:34 pm #12866::Hello, my error position is on the ItemSlotData Script at the Public Bool Stackable method.
the correct code should be this
<code> //Compares the item to see if it can be stacked public bool Stackable(ItemSlotData slotToCompare) { return slotToCompare.itemData == itemData; } </code>
January 2, 2024 at 8:47 pm #12869::I did the way to fix your error but still not. Do you have any other way, thank you very much
January 3, 2024 at 6:56 pm #12927::Hi Đức-65IT1 Hoàng Ngọc, could you show us your code for ItemSlotData, InventoryManager and UIManager?
January 3, 2024 at 11:28 pm #12940::here is ItemslotData code
[System.Serializable] public class ItemSlotData { public ItemData itemData; public int quantity; //Class Constructor public ItemSlotData(ItemData itemData, int quantity) { this.itemData = itemData; this.quantity = quantity; ValidateQuantity(); } //Automatically construct the class with the item data of quantity 1 public ItemSlotData(ItemData itemData) { this.itemData = itemData; quantity = 1; ValidateQuantity(); } //Clones the ItemSlotData public ItemSlotData(ItemSlotData slotToClone) { itemData = slotToClone.itemData; quantity = slotToClone.quantity; } //Stacking System //Shortcut function to add 1 to the stack public void AddQuantity() { AddQuantity(1); } //Add a specified amount to the stack public void AddQuantity(int amountToAdd) { quantity += amountToAdd; } public void Remove() { quantity--; ValidateQuantity(); } //Compares the item to see if it can be stacked public bool Stackable(ItemSlotData slotToCompare) { return slotToCompare.itemData == itemData; } //Do checks to see if the values make sense private void ValidateQuantity() { if (quantity <= 0 || itemData == null) { Empty(); } } //Empties out the item slot public void Empty() { itemData = null; quantity = 0; } }
January 3, 2024 at 11:29 pm #12941::here is InventoryManager code
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Inventorymanager : MonoBehaviour { public static Inventorymanager Instance { get; private set; } private void Awake() { // if there is more than one instance, destroy the extra if (Instance != null && Instance != this) { Destroy(this); } else { Instance = this; } } [Header("Tools")] //Tool Slots [SerializeField] private ItemSlotData[] toolSlots = new ItemSlotData[8]; // Tool in the player's hand [SerializeField] private ItemSlotData equippedToolSlot = null; [Header("Item")] //Items Slots [SerializeField] private ItemSlotData[] itemSlots = new ItemSlotData[8]; //Item in the player's hand [SerializeField] private ItemSlotData equippedItemSlot = null; // vi tri giup nguoi dung nhat do public Transform handPoint; // equiping // Handles movement of item from inventory to hand public void InventoryToHand(int slotIndex, InventorySlot.InventoryType inventoryType) { //The slot to equip (Tool by default) ItemSlotData handToEquip = equippedToolSlot; //The array to change ItemSlotData[] inventoryToAlter = toolSlots; if (inventoryType == InventorySlot.InventoryType.Item) { //Change the slot to item handToEquip = equippedItemSlot; inventoryToAlter = itemSlots; } //Check if stackable if (handToEquip.Stackable(inventoryToAlter[slotIndex])) { ItemSlotData slotToAlter = inventoryToAlter[slotIndex]; //Add to the hand slot handToEquip.AddQuantity(slotToAlter.quantity); //Empty the inventory slot slotToAlter.Empty(); } else { //Not stackable //Cache the Inventory ItemSlotData ItemSlotData slotToEquip = new ItemSlotData(inventoryToAlter[slotIndex]); //Change the inventory slot to the hands inventoryToAlter[slotIndex] = new ItemSlotData(handToEquip); //Change the Hand's Slot to the Inventory Slot's handToEquip = slotToEquip; } //Update the changes in the scene if (inventoryType == InventorySlot.InventoryType.Item) { RenderHand(); } //Update the changes to the UI UIManager.Instance.RenderInventory(); } // Handles movement of item from hand to inventory public void HandToInventory(InventorySlot.InventoryType inventoryType) { } // Render the player's equiped item in the scene public void RenderHand() { //Reset objects on the hand if(handPoint.childCount > 0) { Destroy(handPoint.GetChild(0).gameObject); } // Check if player has anything equiped if(equippedItemSlot != null) { // Instantiate the game model on the player's hand and put it on the scene Instantiate(GetEquippedSlotItem(InventorySlot.InventoryType.Item).gameModel, handPoint); } } // Inventory Slot Data #region Get and Checks //Get the slot item (ItemData) public ItemData GetEquippedSlotItem(InventorySlot.InventoryType inventoryType) { if (inventoryType == InventorySlot.InventoryType.Item) { return equippedItemSlot.itemData; } return equippedToolSlot.itemData; } //Get function for the slots (ItemSlotData) public ItemSlotData GetEquippedSlot(InventorySlot.InventoryType inventoryType) { if (inventoryType == InventorySlot.InventoryType.Item) { return equippedItemSlot; } return equippedToolSlot; } //Get function for the inventory slots public ItemSlotData[] GetInventorySlots(InventorySlot.InventoryType inventoryType) { if (inventoryType == InventorySlot.InventoryType.Item) { return itemSlots; } return toolSlots; } //Check if a hand slot has an item public bool SlotEquipped(InventorySlot.InventoryType inventoryType) { if (inventoryType == InventorySlot.InventoryType.Item) { return equippedItemSlot != null; } return equippedToolSlot != null; } //Check if the item is a tool public bool IsTool(ItemData item) { //Is it equipment? //Try to cast it as equipment first Equipment equipment = item as Equipment; if (equipment != null) { return true; } //Is it a seed? //Try to cast it as a seed SeedData seed = item as SeedData; //If the seed is not null it is a seed return seed != null; } #endregion // Only for equiping empty slots public void EquipEmptySlot(ItemData item) { if (IsTool(item)) { equippedToolSlot = new ItemSlotData(item); } else { equippedItemSlot = new ItemSlotData(item); } } #region Inventory Slot Validation private void OnValidate() { //Validate the hand slots ValidateInventorySlot(equippedToolSlot); ValidateInventorySlot(equippedItemSlot); //Validate the slots in the inventory ValidateInventorySlots(itemSlots); ValidateInventorySlots(toolSlots); } //When giving the itemData value in the inspector, automatically set the quantity to 1 void ValidateInventorySlot(ItemSlotData slot) { if (slot.itemData != null && slot.quantity == 0) { slot.quantity = 1; } } // validate array //Validate arrays void ValidateInventorySlots(ItemSlotData[] array) { foreach (ItemSlotData slot in array) { ValidateInventorySlot(slot); } } #endregion }
January 3, 2024 at 11:31 pm #12942::here is uimanager code
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; public class UIManager : MonoBehaviour, ITimeTracker { public static UIManager Instance { get; private set; } [Header("Status Bar")] public Image toolEquipSlot; public TextMeshProUGUI timeText; public TextMeshProUGUI dateText; [Header("Inventory System")] public GameObject inventoryPanel; public InventorySlot[] toolSlots; // the tool equip slot UI public HandInventorySlot toolHandSlot; public InventorySlot[] itemSlots; public HandInventorySlot itemHandSlot; //Item info box public TextMeshProUGUI itemNameText; public TextMeshProUGUI itemDescriptionText; private void Awake() { // if there is more than one instance, destroy the extra if (Instance != null && Instance != this) { Destroy(this); } else { Instance = this; } } private void Start() { RenderInventory(); AssignSlotIndex(); // add uimanager to the list of object TimeManager will notify when the time update TimeManager.Instance.RegisterTracker(this); } public void AssignSlotIndex() { for (int i = 0; i < toolSlots.Length; i++) { toolSlots[i].AssignIndex(i); itemSlots[i].AssignIndex(i); } } //Render the inventory screen to reflect the player's Inventory public void RenderInventory() { //Get the respective slots to process ItemSlotData[] inventoryToolSlots = Inventorymanager.Instance.GetInventorySlots(InventorySlot.InventoryType.Tool); ItemSlotData[] inventoryItemSlots = Inventorymanager.Instance.GetInventorySlots(InventorySlot.InventoryType.Item); // Render the Tool slot RenderInventoryPanel(inventoryToolSlots, toolSlots); // Render the Item slot RenderInventoryPanel(inventoryItemSlots, itemSlots); //Render the equipped slots toolHandSlot.Display(Inventorymanager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Tool)); itemHandSlot.Display(Inventorymanager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Item)); //Get Tool Equip from InventoryManager ItemData equippedTool = Inventorymanager.Instance.GetEquippedSlotItem(InventorySlot.InventoryType.Tool); if (equippedTool != null) { // Switch the thumbnail over toolEquipSlot.sprite = equippedTool.thumbnail; toolEquipSlot.gameObject.SetActive(true); return; } toolEquipSlot.gameObject.SetActive(false); } // Interate through a slot in a section and display them in the UI void RenderInventoryPanel(ItemSlotData[] slots, InventorySlot[] uiSlots) { for (int i = 0; i < uiSlots.Length; i++) { //Display them accordingly uiSlots[i].Display(slots[i]); } } public void ToggleInventoryPanel() { // Neu dang an thi hien ra va nguoc lai inventoryPanel.SetActive(!inventoryPanel.activeSelf); RenderInventory(); } public void DisplayItemInfo(ItemData data) { if (data == null) { itemNameText.text = ""; itemDescriptionText.text = ""; return; } itemNameText.text = data.name; itemDescriptionText.text = data.description; } public void ClockUpdate(GameTimestamp timestamp) { // Handle time int hours = timestamp.hour; int minutes = timestamp.minute; string prefix = "AM "; if(hours > 12) { prefix = "PM "; hours -= 12; } timeText.text = prefix + hours + ":" + minutes.ToString("00"); // Handle the date int day = timestamp.day; string season = timestamp.season.ToString(); string dayOfTheWeek = timestamp.GetDayOfTheWeek().ToString(); dateText.text = season + " " + day + "(" + dayOfTheWeek + ")"; } }
January 4, 2024 at 7:18 pm #12998::The problem might be in the
InventoryToHand
function.Could you try replacing in InventoryManager
handToEquip = slotToEquip;
withEquipEmptySlot
? I went through how to do it around the 30 minute mark of the video (renamed it and all).Or try following the tutorial from where you left off from 26:41 to the end and see if you still get this error.
If you still get this error after that let me know if: When you move the tool from inventory to hand, does the Inspector show that you have the tool equipped?
January 5, 2024 at 12:15 am #13011::I have done your way but can’t. When I move the tool from Inventory to my hand there will be two cases: If I had not equipped it into Equipedtoolslot when I moved the tool, the tools containing the tool would turn into Empty. And if I have equipped Equipedtoolslot (Ex: Watering), when I move the tool from Inventory to hand, the Inventory Slot will appear water can if I click on them again, the number of water can Increase in Equipedtoolslot (Sorry I can’t post the video). Thank you very much
January 8, 2024 at 10:19 am #13056January 8, 2024 at 2:11 pm #13058::I have fixed the error thank you too much Jonathan Teo
- 1 anonymous person
January 8, 2024 at 4:47 pm #13062 -
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: