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

Viewing 15 posts - 1 through 15 (of 17 total)
  • Author
    Posts
  • #12069
    Sand Man
    Participant

    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()
        {
            
        }
    }
    
    #12075
    Jonathan Teo
    Moderator

    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 intended

    #12076
    Sand Man
    Participant

    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.

    #12865

    Sand Man Can you send me a picture of the error position? I have a same problem with you

    #12866
    Sand Man
    Participant

    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;
        }
    
    #12869

    I did the way to fix your error but still not. Do you have any other way, thank you very much

    #12927
    Jonathan Teo
    Moderator

    Hi Đức-65IT1 Hoàng Ngọc, could you show us your code for ItemSlotData, InventoryManager and UIManager?

    #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;
        }
    }
    #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
    
    }
    #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 + ")";
        }
    }
    #12998
    Jonathan Teo
    Moderator

    The problem might be in the InventoryToHand function.

    Could you try replacing in InventoryManager handToEquip = slotToEquip; with EquipEmptySlot? 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?

    #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

    #13056
    Jonathan Teo
    Moderator

    What does the InventoryManager class look like now?

    #13058

    I have fixed the error thank you too much Jonathan Teo

    #13062
    Terence
    Keymaster

    Hoàng Ngọc,

    Glad to hear that. What was the issue?

Viewing 15 posts - 1 through 15 (of 17 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: