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 8 months, 1 week ago by Terence.
-
AuthorPosts
-
October 11, 2023 at 6:59 pm #12069Sand ManParticipant::
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 #12075Jonathan TeoModerator::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.
1. Ensure that the SlotIndexes are assigned correctly in UIManager
2. Ensure that the Hand Slots are configured correctly
3. InvSlots Display function is working as intendedOctober 13, 2023 at 5:55 pm #12076Sand ManParticipant::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Đức-65IT1 Hoàng NgọcParticipant::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 #12866Sand ManParticipant::Hello, my error position is on the ItemSlotData Script at the Public Bool Stackable method.
the correct code should be this
//Compares the item to see if it can be stacked public bool Stackable(ItemSlotData slotToCompare) { return slotToCompare.itemData == itemData; }
January 2, 2024 at 8:47 pm #12869Đức-65IT1 Hoàng NgọcParticipant::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 #12927Jonathan TeoModerator::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Đức-65IT1 Hoàng NgọcParticipant::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Đức-65IT1 Hoàng NgọcParticipant::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Đức-65IT1 Hoàng NgọcParticipant::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 #12998Jonathan TeoModerator::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Đức-65IT1 Hoàng NgọcParticipant::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 #13056Jonathan TeoModeratorJanuary 8, 2024 at 2:11 pm #13058Đức-65IT1 Hoàng NgọcParticipantJanuary 8, 2024 at 4:47 pm #13062 -
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: