Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

2D Inventory System

Discussion in '2D' started by Ahmed-C, Dec 24, 2015.

  1. Ahmed-C

    Ahmed-C

    Joined:
    Dec 19, 2013
    Posts:
    10
    Pretty much title says it all. I'm trying to implement a basic Inventory system where:
    1. Player can pick up items from the scene
    2. Picked up items get stored in the inventory
    3. Selected items can be used and once they are used they are removed from the inventory.
    My problem is that I can't really seem to decide what is the best method. I've been searching around and pretty much a lot of posts mention that there aren't specific ways to do this it really is a matter of how YOU want to achieve it. That being said, I have a new way but let me explain my previous way.

    Previous way (didn't work, couldn't get it to work properly)
    - Idea was to create a list which takes gameObjects of those items and store them in the list. The list acts as the inventory so 15 elements means that there are 15 items in the list. Problem was that each time I picked up the item, I wanted to destroy the item from the scene but I couldn't achieve this because as I added the gameObject to the list, then destroyed the gameObject from the scene, since the added listItem is referencing gameObject from the script, destroying the script destroys the gameObject from the inventory. Essentially I'm adding a null each time. After much trying, I got no where and ended up doing the same thing in different ways.

    New Way (hoping to this)
    - I choose the previous way to start with is because I wanted the picked up Items from the scene to be deleted for the game to be 'efficient' in having/managing items in the scene. I realized that I barely have too many items at the moment in my scene so the new way would simply be hiding items using:
    Code (CSharp):
    1. GetComponenet<Renderer>.enabled = true/false
    I just want to know whether there would be some sort of impact if I just have items in the scene then just hiding them and showing them when the player selects that item from the inventory.

    Take The Forest as an example. Built in Unity, has an Inventory system. I'm wondering if the items that the player has are the items that have been moved from Position A (point of origin) to Position B (players inventory space)?

    TL;DR - Just want to know whether hiding/showing is better than deleting and recreating objects when it comes to inventory system and picking up etc.
     
  2. LiberLogic969

    LiberLogic969

    Joined:
    Jun 29, 2014
    Posts:
    138
    Instead of having a GameObject represent an actual Item why not have it act as an ItemContainer. The ItemContainer holds all the data for the item it represents. When your player collides with an ItemContainer you grab the Item data from it and add THOSE values to your inventory and then destroy (or pool) the ItemContainer gameobject. How you represent the actual item data is up to you. You could have an "ItemDatabase" which holds the data for each Item in your game, and your inventory manages either instances of that data or a reference to it.

    Here is an example of what I mean (this is all pseudo code off the top of my head so bear with me :p) :

    Code (CSharp):
    1. using System;
    2.  
    3. [Serializable]
    4. public class ItemData
    5. {
    6.        public string UniqueID;
    7.        public Sprite Icon;
    8.        public string DisplayName;
    9.        public string Description;
    10.        public ItemRarity RarityRating;
    11.        public int MaxInventoryStack;
    12.        // etc...........
    13. }
    14.  
    15. //-----------------------------------------------------------//
    16.  
    17. using UnityEngine;
    18. using System.Collections.Generic;
    19.  
    20. public class ItemDatabase : MonoBehavior
    21. {
    22.        // Singleton reference
    23.        public static ItemDatabase Instance;
    24.  
    25.        // Create Items in the Inspector
    26.        public ItemData[] Items;
    27.        // store them in a useful collection type
    28.        private Dictionary<string, ItemData> master_Items;
    29.      
    30.        public void Awake()
    31.        {
    32.              Instance = this;
    33.              master_Items = new Dictionary<string, ItemData>();
    34.              CreateDatabase();
    35.        }
    36.        private void CreateDatabase()
    37.        {
    38.                for (int i = 0; i < Items.Length; i++)
    39.                {
    40.                       ItemData itemData = Items[i];
    41.                       if (!master_Items.ContainsKey(itemData.UniqueID))
    42.                       {
    43.                             master_Items.Add(itemData.UniqueID, itemData);
    44.                       }
    45.                       else Debug.LogError("Item : " + itemData.DisplayName + " Shares the same UniqueID with another Item");
    46.                }
    47.        }
    48.        public ItemData GetItemData(string id)
    49.        {
    50.               if (master_Items.ContainsKey(id))
    51.                  return master_Items[id];
    52.               else return null;
    53.        }
    54. }
    55. //-----------------------------------------------------------//
    56.  
    57. using UnityEngine;
    58. using System;
    59.  
    60. public class InventoryManager : MonoBehavior
    61. {
    62.       [Serializable]
    63.       public class ItemEntry
    64.       {
    65.             public string ItemID;
    66.             public int Amount;
    67.  
    68.             public ItemEntry(string _itemID, int _amount)
    69.             {
    70.                    ItemID= _itemID;
    71.                    Amount = _amount;
    72.             }
    73.       }
    74.  
    75.       private List<ItemEntry> itemsInInventory;
    76.  
    77.       public void AddItem(string id, int amount)
    78.       {
    79.            ItemEntry newEntry = new ItemEntry(id, amount);
    80.          
    81.            // do your inventory stuff...
    82.       }
    83. }
    84.  
    85. //-----------------------------------------------------------//
    86. using UnityEngine;
    87.  
    88. public class ItemContainer : MonoBehavior
    89. {
    90.        public string ContainedItemID;
    91.        public int AmountContained;
    92.  
    93.        void OnCollisionEnter2D(Collider2D other)
    94.       {
    95.                 if (other.gameObject.tag == "Player")
    96.                 {
    97.                       other.gameObject.GetComponent<InventoryManager>().AddItem(ContainedItemID, AmountContained);
    98.  
    99.                       Destroy(gameobject);
    100.                 }
    101.       }
    102. }
    103.  
    104. }
    Hope you find this useful!
     
  3. Ahmed-C

    Ahmed-C

    Joined:
    Dec 19, 2013
    Posts:
    10
    Thank you, I manage to make something work out of it, now I'm gonna modify that and try to improve it and suit my needs :D