CS2335
Master_v2
Master_v2
  • Introduction
  • Introduction
    • Introduction
      • Design
      • Game Design
    • Unity - Download
    • Visual Studio - IDE
    • Hero's Journey
  • Unity Basics
    • Unity Editor Windows
    • MonoBehavior - Base-Class
    • Unity Engine - Event Functions
  • Getting Started
    • UI-Elements
    • Animator Controller
      • Animation Steps
    • PlayerController Flow Chart
    • PlayerController Code
      • PlayerController - V1 - S20
      • PlayerController V2 S20
      • PlayerController V3 S20
  • Project 1 - Simple Game
    • Overview
    • Project 1 - Get Started
      • UML Class Diagram
    • Player GameObject
      • PlayerController.cs V2
      • PlayerController.cs V3
    • Create 2D Sprite Prefab: Rock
    • Sorting Layers
  • Project1 Code
    • PickUp PreFabs
    • Player GameObject
    • PlayerController - jump
    • GameData Version1
    • PlayerStats Version1
    • MiniGameManager
      • Logic Diagram
    • Simple Spawner
    • Utility Class
  • Project1 Enhancements
    • PickUp - SelfDestruct
    • Spawn from List of Prefabs
  • Project 2 - StateManager
    • Project 2 - Learning Objectives
    • Project 2 - Starter Assets
    • Project 2
      • State Machine Framework
        • Singleton Pattern
      • StateManager - Singleton Design Pattern
      • IStateBase, BeginState
      • Project 2 -Steps: Create new Scene and State
      • Project 2 - List of Steps
        • Project 2 - Starter Code
  • Project 2 -Dialog
    • Hide_Show_Panel Script
    • Configure TitlePanel, DecisionPanel
    • Simple Dialog Prefab
    • Conversation Scriptable Objects
    • DialogManager_ConvList
    • Image Transitions for Buttons
  • UI Components
    • Finding Game Objects
    • Game Objects: UI vs. 2D Sprite
    • UI Elements
      • Canvas: Screen-Space Render-Mode
      • UI-Buttons To Change Scene
      • Text Input
  • Project2 Resources
    • Visual Novel in Unity-Links
    • Scriptable Object Factory
      • ScriptableObjects
    • Dialog Prefab Packages
  • Project 3 - Overview
    • Branching Story Structures
    • Dictionary Data-Structure
      • Unity PlayerPrefs Dictionary
    • Dictionary: User-Choice Data
      • User-Choices - Example
        • Dictionary Value to Disable Options
    • Simplified Mini-Game
      • PlayerController_v2 Mods
        • PlayerController_v2_final
      • MiniGameManager_v2
  • Proj3: Inventory System
    • Inventory-System
      • Install and Configure
      • Diagrams, Resources
        • Item, Gem, Potion Classes
        • Inventory Class
      • InventoryDisplay, Slot UI
        • InventoryDisplay Class
        • Slot Class
        • Hazard Class
        • Layout Groups
      • Customization Steps
        • Configure Animation
        • AddItem Button
        • Concrete Class: Food
        • MiniGame Mods
          • PlayerController Mods
      • Code: InventorySystem
        • GameData, PickUp Mods
      • Resources: Data Structures
  • Proj3: Custom UnityEvents
    • Event Publishing Patterns
    • Custom Event Messaging
  • Proj3: Mini-Game
    • MiniGame-Overview-Proj3
    • LevelManager
      • LevelManager Logic Diagram
      • LevelManager FSM
      • LoadLevel, StartLevel Logic
      • Code Framework
    • Timer
  • Project 3 - Code Mods
    • Project 3 - Steps
    • Project 3 - Code
      • Code: Final Versions
        • PlayerController Mods
          • PlayerController_v2 Mods
        • GameData - Final
        • LevelManager
        • PlayerStats - Final
        • PickUp, Hazard, ScorePickUp
        • Spawner - Final
        • CameraFollow
        • ScreenFader
        • MiniGameState
        • Example: EndState
      • MiniGameWin Logic
  • Optional, Supplemental Content
    • Optional Content
      • Adding Audio
      • Screen Fading and Reloading
      • ScriptableObjects
      • Disable Debug Logging
      • Events and Actions
      • Saving Data - Serialization
      • Parallax Scrolling
      • Change Sprites
  • C# Language
    • C# Language
      • Variables
      • Enum
      • Encapsulation
        • C# Properties
        • Access Modifiers
      • Inheritance
      • Polymorphism
      • Interface
      • Switch-Case
      • List< T >
      • Queue< T >
      • Dictionary
      • Foreach
      • Static
      • Ternary Operator: ?
      • this
      • Delegates
    • Diagrams
      • State Machine Framework
      • UML Class Diagrams
      • Level Manager Logic Diagram
      • Flow-Chart: NumberGame
      • FSM: NumberGame
    • Glossary
    • References and Resources
    • Random Thoughts
Powered by GitBook
On this page
  • Updated InventorySystem
  • Inventory Class
  • InventoryDisplay Class
  • Slot Class

Was this helpful?

  1. Proj3: Inventory System
  2. Inventory-System

Code: InventorySystem

Updated InventorySystem

Updated: 4/3/2020

If you update all scripts below, then your Inventory display all items correctly:

The initial version of InventorySystem had the InventoryDisplay use ItemInstance as the key for the dictionary of item Counts. Instead, we want to use item as the dictionary key.

In the entire project, there is one item, and many itemInstances. The ItemInstance is a wrapper class that will allow easy expansion to include additional attributes to our inventory items. So, in that case, if we had good, better, best qualities, then we'd need to decide the best way to display those.

Required Code Changes - Code listed below

  • Inventory.cs

  • InventoryDisplay.cs

  • Slot.cs

Inventory Class

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

//modified from
////https://github.com/Toqozz/blog/blob/master/inventory

[System.Serializable]
public class Inventory : ScriptableObject
{
    public UnityEvent onInventoryUpdate = new UnityEvent();

    /* Inventory START */
    public List<ItemInstance> inventory;  // - initialized in inspector

    public void OnEnable()
    {
        if (inventory == null)
        {
            inventory = new List<ItemInstance>();
        }
        else
        {
            inventory.Clear();
        }
    }

    public bool SlotEmpty(int index)
    {
        if (inventory[index] == null || inventory[index].item == null)
        {
            Debug.Log(" empty slot");
            return true;
        }
        return false;
    }

    // Remove an item at an index if one exists at that index.
    public bool RemoveItem(ItemInstance item)
    {
        return (inventory.Remove(item));  //returns true/false
    }

    // Insert an item, return the index where it was inserted.  -1 if error.
    public void InsertItem(ItemInstance item)
    {

        Debug.Log("item added to inventory " + item.item.name);
        inventory.Add(item); //add to list 

        ///Broadcast event to notify listeners
        if (onInventoryUpdate != null)
        {
            onInventoryUpdate.Invoke();
        }

    } //end method

} //end class

InventoryDisplay Class

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

//modified from
////https://github.com/Toqozz/blog/blob/master/inventory

public class InventoryDisplay : MonoBehaviour
{
    private List<Slot> inventorySlots;
    private Inventory inventory;
    public Dictionary<ItemInstance, int> itemCounts =  new Dictionary<ItemInstance, int>(); //dictionary
    public const int NumSlots = 4;
    public int displayedRowPointer=0; //
    Animator visibilityAnimator;
    public bool isVisible = false;

        // Use this for initialization
    void Start()
    {
        inventory = GameData.instanceRef.inventory;
        //inventoryDisplay wants to be notified when inventory changes
        inventory.onInventoryUpdate.AddListener(UpdateDisplay);

        // Load example
        inventorySlots = new List<Slot>();
        //add child slots to the inventorySlots list.
        inventorySlots.AddRange(Object.FindObjectsOfType<Slot>());

        // Maintain some order (just in case it gets screwed up).
        inventorySlots.Sort((a, b) => a.index - b.index);
        SetSlotIndexes();
        PopulateInitial();
        visibilityAnimator = GetComponent<Animator>();
        visibilityAnimator.SetBool("IsVisible", false);
    }

    private void Update()
    {
        if( Input.GetKeyUp( KeyCode.Tab))
        {
            isVisible = !isVisible;
            visibilityAnimator.SetBool("IsVisible", isVisible);
        }
    }

    //update itemCount dictionary: items, counts - get data from
    //inventory
    //condense data into key-value pairs:  item: count
    private void UpdateItemCounts()
    {
        itemCounts.Clear(); //clear out dictionary
         //for all items-slots in the inventory
         //count the number of identical items - 
         //put unique item in dictionary/ with count as value
        for( int i=0; i< inventory.inventory.Count; i++)
        {
            //for each item-slot in data inventory
            //if the slot has an item
            //add key to dictionary, update count

            if (!inventory.SlotEmpty(i)) //is there an item in the inventory for each list item?
            {
                ItemInstance item = inventory.inventory[i];
                int count;
                if (itemCounts.TryGetValue(item, out count))
                {
                    itemCounts[item] = ++count; //if already added, increment count
                }
                else
                {
                    itemCounts.Add(item, 1); //add item
                }
            }
        }
    }

    private void PopulateInitial()
    {
        UpdateItemCounts(); //populate dictionary
        if( itemCounts.Count > 0) { //something in the dictionary
        int index = 0;
            //get the keys (all existing items) 
            Dictionary<ItemInstance, int>.KeyCollection keys = itemCounts.Keys;
            //loop through all instance-count pairs
            foreach (ItemInstance instance in keys)
            {
                if (index < NumSlots) //fill the first 4 slots
                {
                    int value = itemCounts[instance];//use current key-item to get the count (value)
                   // Debug.Log("PopulateInitial:item count" + value );
                    if (instance != null)
                    {
                        //Update the slot, by adding an item
                        inventorySlots[index].SetItem(instance, value);
                        index++; //move to next slot
                    }
                }
                else
                {

                  //  Debug.Log("more items than slots, some not displayed");
                }
            }
        }

    } //end method

    void SetSlotIndexes()
    {
        foreach( Slot slot in inventorySlots)
        {
            slot.index = inventorySlots.IndexOf(slot);
        }
    }

    public void RemoveItem(ItemInstance item, int index )
    {
        int count;
        if(itemCounts.TryGetValue( item, out count))
        {
            if( count <= 1) //if the last one
            {

                itemCounts.Remove(item); //remove from dictionary itemCounts
                inventorySlots[index].RemoveItem(index);//remove from slot display
                inventory.RemoveItem(item); //remove from data inventory
            }
            else
            {
                itemCounts[item] = count - 1;  //decrease
                inventorySlots[index].SetItem(item, count-1);
                inventory.RemoveItem(item);
            }
          
        }
    }


    public void UpdateDisplay()
    {
        Clear();
        PopulateInitial();
    }

    //Adds an item to the itemCount dictionary
    //or updates the count if item was already in the dictionary
    void AddToCounts(ItemInstance item)
    {
        int count;
        if (itemCounts.TryGetValue(item, out count))
        {
            itemCounts[item] = ++count;
            Debug.Log("itemCount " + item.item.itemName + " " + count);
        }
        else if (itemCounts.Count <= NumSlots) //we still have an available slot
        {
            itemCounts.Add(item, 1); //add first item
        }
    }

   private void Clear()
    {
        for (int i = 0; i < inventorySlots.Count; i++)
        {
            inventorySlots[i].RemoveItem(i);
        }
    }

    //unregister listener when this object is destroyed 
    private void OnDisable()
    {
        inventory.onInventoryUpdate.RemoveListener(UpdateDisplay);
    }

} //end class InventoryDisplay

Slot Class

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

//modified from
////https://github.com/Toqozz/blog/blob/master/inventory

public class Slot : MonoBehaviour, IPointerClickHandler
{
    
    InventoryDisplay inventoryDisplay; 
    public int index = 0; //is auto-set within Physical ScriptableObject Inventory
    public ItemInstance itemInstance = null;    // Inventory backend representation.
    public Image childImage;
    public Text childText;
 
    void Start() //there must only be 1 Inentory display
    {
        inventoryDisplay = FindObjectOfType<InventoryDisplay>();

    }


    //Detect if a click occurs
    public void OnPointerClick(PointerEventData pointerEventData)
    { //check to see if an item is in the slot!
        if (itemInstance.item != null)
        {
            itemInstance.item.Use();
            inventoryDisplay.RemoveItem(itemInstance, index);
            //TODO USE and REMOVE ITEM
            //Output to console the clicked GameObject's name and the following message. You can replace this with your own actions for when clicking the GameObject.
            Debug.Log(name + " Game Object Clicked for Use( )");
        }
    }


    //Changing the default sprite in the slot to this instance's sprite
    //Change alpha to full ( white color is full opacity )
    public void SetItem(ItemInstance instance, int count)
    {
        if (instance != null)
        {
            this.itemInstance = instance;
            this.childImage.sprite = instance.item.sprite;
            this.childImage.preserveAspect = true;
            this.childImage.color = Color.white;
            this.childText.color = Color.white;
            this.childText.text = count.ToString();
        }
    }

    // Remove the sprite from the slot, reset color from white to clear
    public void RemoveItem(int index)
    {
        if (this.index == index) //check it is the slot's current index
        {
            this.itemInstance = null;
            this.childImage.sprite = null;
            this.childImage.color = Color.clear;
            this.childText.color = Color.clear;
        }
    }
} //end class Slot
PreviousPlayerController ModsNextGameData, PickUp Mods

Last updated 5 years ago

Was this helpful?