Search Unity

Control Inventory with Keyboard or Gamepad

Discussion in 'Input System' started by Tompis1995, Apr 7, 2022.

  1. Tompis1995

    Tompis1995

    Joined:
    Feb 3, 2022
    Posts:
    14
    I'm having an extremely difficult time trying to implement a basic cursor controlled by the keyboard or game controller that operates an inventory. I looked up and down the web for inventory tutorials but almost all of them use the mouse to navigate the inventory. The tutorials on pause menus don't really work for me because the inventory system I want to implement does not have a fixed number of buttons, that is, items. That setup requires me to load a first "selected item" which may or may not be available. I also can't simply make a placeholder "item" when no items exist because I have the code set up to clear all of the contents whenever the inventory is updated. I need help! Thanks!

    Code for Inventory Manager:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using TMPro;
    5.  
    6. public class InventoryManager : MonoBehaviour
    7. {
    8.  
    9.     [Header("Inventory information")]
    10.     public PlayerInventory playerInventory;
    11.     [SerializeField] private GameObject blankInventorySlot;
    12.     [SerializeField] private GameObject inventoryPanel;
    13.     // The "Content" part of the Viewport in the Inventory Menu
    14.     [SerializeField] private TextMeshProUGUI descriptionText;
    15.     [SerializeField] private GameObject equipButton;
    16.     public InventoryItems currentItem;
    17.     public Animator inventoryAnimator;
    18.     public bool InventoryOpen;
    19.     private bool StartInit;
    20.     public InventoryCursor cursor;
    21.     [SerializeField] private GameObject noItems;
    22.     //'InventoryOpen' will help prevent the Inventory menu from automatically sliding back
    23.     // up off screen to its inactive state right after being summoned. The same is true for the
    24.     // other way around; The bool also prevents the menu from re-opening automatically right
    25.     // after being closed.
    26.  
    27.     public void PullDownInventory()
    28.     {
    29.         if (!InventoryOpen)
    30.         {
    31.             inventoryAnimator.SetTrigger("InventoryActive");
    32.             InventoryOpen = true;
    33.         }
    34.     }
    35.  
    36.     public void CloseInventory()
    37.     {
    38.         if (InventoryOpen)
    39.         {
    40.             inventoryAnimator.SetTrigger("InventoryInactive");
    41.             InventoryOpen = false;
    42.         }
    43.     }
    44.  
    45.     public void SetTextAndButton(string description, bool buttonActive)
    46.     {
    47.         descriptionText.text = description;
    48.         if (buttonActive)
    49.         {
    50.             equipButton.SetActive(true);
    51.         } else
    52.         {
    53.             equipButton.SetActive(false);
    54.         }
    55.     }
    56.  
    57.     void MakeInventorySlot()
    58.     {
    59.         if (playerInventory)
    60.         // If the Player Inventory exists...
    61.         {
    62.             for (int i = 0; i < playerInventory.myInventory.Count; i++)
    63.             // Go through all existing slots starting at 0.
    64.             {
    65.                 if (playerInventory.myInventory[i].numberHeld > 0)
    66.                 {
    67.  
    68.  
    69.                     GameObject temp = Instantiate(blankInventorySlot, inventoryPanel.transform.position, Quaternion.identity);
    70.                     temp.transform.SetParent(inventoryPanel.transform);
    71.                     InventorySlot newSlot = temp.GetComponent<InventorySlot>();
    72.                     newSlot.transform.SetParent(inventoryPanel.transform);
    73.  
    74.                     if (newSlot)
    75.                     {
    76.                         newSlot.Setup(playerInventory.myInventory[i], this);
    77.  
    78.                     }
    79.                     Debug.Log("I contain " + currentItem + " and my integer is " + i);
    80.  
    81.                     if (StartInit && i == 0)
    82.                     {
    83.                         cursor.InitCursor(inventoryPanel);
    84.                         StartInit = false;
    85.                     }
    86.  
    87.                 } if (playerInventory.myInventory.Count == 0)
    88.                 {
    89.                     GameObject other = Instantiate(noItems, inventoryPanel.transform.position, Quaternion.identity);
    90.                     other.transform.SetParent(inventoryPanel.transform);
    91.                     InventorySlot newSlot = other.GetComponent<InventorySlot>();
    92.                     newSlot.transform.SetParent(inventoryPanel.transform);
    93.                 }
    94.             }
    95.         }
    96.     }
    97.  
    98.     private void Start()
    99.     {
    100.         StartInit = true;
    101.         InventoryOpen = false;
    102.         // The inventory, by default, should always be inactive, or at least off screen,
    103.         // when the game starts.
    104.         ClearInventorySlots();
    105.         MakeInventorySlot();
    106.  
    107.     }
    108.  
    109.     private void OnEnable()
    110.     {
    111.         SetTextAndButton("", false);
    112.     }
    113.     // Start is called before the first frame update
    114.     public void UpdateInventory()
    115.     {
    116.         ClearInventorySlots();
    117.         MakeInventorySlot();
    118.        
    119.     }
    120.     public void Update()
    121.     {
    122.         if(GameObject.FindGameObjectWithTag("Player").GetComponent<Health>().dead)
    123.         {
    124.             Destroy(this.gameObject);
    125.         }
    126.     }
    127.     // Update is called once per frame
    128.     public void SetupDescriptionAndButton(string newDescriptionString, bool buttonAvailable, InventoryItems newItem)
    129.     {
    130.         currentItem = newItem;
    131.         descriptionText.text = newDescriptionString;
    132.         equipButton.SetActive(buttonAvailable);
    133.     }
    134.  
    135.     public void ClearInventorySlots()
    136.     {
    137.         for(int i = 0; i < inventoryPanel.transform.childCount; i++)
    138.         {
    139.             Destroy(inventoryPanel.transform.GetChild(i).gameObject);
    140.             Debug.Log("I destroyed " + inventoryPanel.transform.GetChild(i).gameObject + "and its integer was "
    141.                + i + " and its coordinates were " + inventoryPanel.transform.GetChild(i).gameObject.transform.position.x + " x and "
    142.                + inventoryPanel.transform.GetChild(i).gameObject.transform.position.y);
    143.         }
    144.     }
    145.  
    146.     public void EquipBoxMarked()
    147.     {
    148.         if (currentItem)
    149.         {
    150.             currentItem.Equip();
    151.             ClearInventorySlots();
    152.             MakeInventorySlot();
    153.             if (currentItem.numberHeld == 0)
    154.             {
    155.                 SetTextAndButton("", false);
    156.                 // Keep the description and equip checkbox button active until the item
    157.                 // reaches zero.
    158.             }
    159.         }
    160.     }
    161. }
    162.  

    For the sake of space, I'm not including all associated codes in this post, but if you need me to post them, let me know. Thanks again!
     
  2. Tompis1995

    Tompis1995

    Joined:
    Feb 3, 2022
    Posts:
    14
    Keep in mind that I'm using the scroll view method for this.
     
  3. SamuelKoprda

    SamuelKoprda

    Joined:
    Jul 30, 2019
    Posts:
    1
    Drat, I am trying to make a mousless inventory too.

    I have actualy implemented something, but it doesnt work that well.
    I simply load the items into a grid, then I have an index telling me what item I have selected, then when player presses left/right I add 1/-1 to the index, going up/down is same, you just add/subtract the width of the grid.

    Then for moving items you can have a select button, that saves the curent index and a move button which switches the times in the curent index and the saved index.

    I have also implemented a shop system using buttons and the unity input UI thingy, which does this movement and idnex coutning for you, so you dont have to do index counting and what not. Problem is, when you press a button it only detects that it is pressed, not what button whas pressed, so you can only do simple stuff, like buying items in a shop.

    I am trying to find a way where you can combine both of theese aproches, have unity autoselect and navigate the inventory, but then have diferent functionality based on what buttons you press. I think that it is possible to do, I just havent figured it out yet