Search Unity

Question How can I check if there are all the items in a list AND the correct quantity using this system?

Discussion in 'Scripting' started by isaaced1115, Jan 3, 2024.

  1. isaaced1115

    isaaced1115

    Joined:
    Dec 28, 2023
    Posts:
    4
    I have a script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor.Experimental.GraphView;
    4. using UnityEngine;
    5.  
    6. public class CraftingMenu : MonoBehaviour
    7. {
    8.     public List<Slot> slots = new List<Slot>();
    9.     public List<Item> items = new List<Item>();
    10.     public Transform craftableSpawn;
    11.     public Inventory inventory;
    12.     private List<Item> recipe;
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.         foreach (Slot slot in slots) //For each slot, initialize that slot
    17.         {
    18.             slot.initializeSlot();
    19.         }
    20.         for (int i = 0; i < items.Count; i++) //Sets all the items in the slots at start
    21.         {
    22.             slots[i].setItem(items[i]);
    23.         }
    24.     }
    25.  
    26.     // Update is called once per frame
    27.     void Update()
    28.     {
    29.         for (int i = 0; i < slots.Count; i++) //For all slots, check if they are being hovered over and if the player clicks on it
    30.         {
    31.             if (Input.GetMouseButtonDown(0) && slots[i].hovered == true)
    32.             {
    33.                 CheckItems(slots[i].getItem());//Checks to see if item is craftable              
    34.                 break;
    35.             }
    36.         }
    37.     }
    38.  
    39.     public void CheckItems(Item item)//Check if all items are in the inventory
    40.     {
    41.         int amountNeeded = item.recipe.Count;
    42.         for (int i = 0; i < item.recipe.Count; i++)
    43.         {
    44.             foreach (Slot slot in inventory.inventorySlots)
    45.             {
    46.                 if (slot.heldItem != null)
    47.                 {
    48.                     if (slot.heldItem.name == item.recipe[i].name)
    49.                     {
    50.                         amountNeeded -= 1;
    51.                     }
    52.                 }
    53.             }
    54.         }
    55.         if (amountNeeded <= 0)
    56.         {
    57.             CraftItem(item);
    58.         }
    59.         else
    60.         {
    61.             Debug.Log("Not enough items to craft this Recipe!");
    62.         }
    63.     }
    64.  
    65.     public void CraftItem(Item item)//Crafts the item
    66.     {      
    67.         int amountNeeded = item.recipe.Count;
    68.         for (int i = 0; i < item.recipe.Count; i++)
    69.         {
    70.             foreach (Slot slot in inventory.inventorySlots)
    71.             {
    72.                 if(slot.heldItem != null)
    73.                 {
    74.                     if (slot.heldItem.name == item.recipe[i].name && slot.heldItem.currentQuant != 0)
    75.                     {
    76.                         amountNeeded -= 1;
    77.                         slot.heldItem.currentQuant -= 1;
    78.                         if(slot.heldItem.currentQuant == 0)
    79.                         {
    80.                             slot.heldItem = null;
    81.                             slot.setItem(slot.heldItem);
    82.                             slot.updateData();
    83.                         }
    84.                     }
    85.                 }              
    86.             }          
    87.         }
    88.         if (amountNeeded <= 0)
    89.         {
    90.             Debug.Log("Item crafted!");
    91.             Item craftable = Instantiate(item, craftableSpawn.position, Quaternion.identity);
    92.             inventory.addItemToInventory(craftable);
    93.             amountNeeded = item.recipe.Count;
    94.         }
    95.         else
    96.         {
    97.             Debug.Log("Something went wrong in the 'CraftItem' function in the 'CraftingMenu' script!");
    98.         }
    99.  
    100.     }  
    101. }
    102.  
    103.  
    So in this script, the players items in their inventory are checked first ("CheckItems()") in order to determine if they have the items needed to craft the item. It then sends this off to the "CraftItem()" function. This works, but as of right now, the script only verifies if they have the same items with the same name in their inventory, NOT the quantity as well. I'm not sure how to compare those things because the recipe stores each item individually so if a recipe for a bow takes 3 sticks and a vine, instead of it being 3 sticks and a vine, it's a stick, a stick, a stick, and a vine. How can I count all the sticks in item.recipe and store it as a value? Am I going about this the wrong way?
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,922
    You probably just want to aggregate the items you need from a recipe first before checking if you have enough in your inventory.

    So if a recipe requires stick, stick, stick and vine, run through the crafting recipe and tally all the items needed, perhaps storing it in a
    Dictionary<Item, int>
    . So the aforementioned becomes Stick x 3, Vine x 1. Then it's easier to check if there's enough items in the players inventory.

    Side note, comparing items by name is pretty flaky. If the items are scriptable objects then you can just compare them directly (== operator). Otherwise I'd implement an explicit comparison method, which is usually best done by implement
    IEquatable<T>
    .
     
    samana1407 likes this.