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
  4. Dismiss Notice

Item Stacking

Discussion in 'Scripting' started by FurionStudios, Dec 12, 2020.

  1. FurionStudios

    FurionStudios

    Joined:
    Sep 23, 2020
    Posts:
    4
    Hi, I'm trying to make my items in a list stack, but I keep getting an error and a warning that I don't know the fix for, can someone help me?
    upload_2020-12-12_10-59-49.png
    These are the warning and the error
    upload_2020-12-12_11-0-50.png
    upload_2020-12-12_11-1-4.png
    upload_2020-12-12_11-1-46.png
    These are the scripts I'm using, what's wrong?

    I need an answer ASAP because this is a project for school.
     
  2. FurionStudios

    FurionStudios

    Joined:
    Sep 23, 2020
    Posts:
    4
    upload_2020-12-12_11-3-54.png
    I forgot to add the Item script
     
  3. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    When asking for help with an error, always make it clear exactly which line of code the error occurs on (if there is one). It's also a good idea to post your code using code tags rather than screenshots.

    A null reference exception is a common error that occurs when you try to make use of a variable that doesn't have a valid value. It usually occurs when you write a period:
    myVariable.something
    will give an error if "myVariable" is null. Find the line that's giving the error, find the periods on that line, figure out which one of the things just before a period doesn't have a valid value.

    The other error is because ScriptableObjects are special and you aren't supposed to create them on your own; since they are a Unity type, you have to go through Unity to make more of them. It's also pretty unusual to be creating more of them like you're doing. Are you sure that (1) you really want Item to be a ScriptableObject, and (2) if so, you really want to create new instances of that class, rather than just passing around references to existing instances?

    If it were me, I might use a ScriptableObject class to represent a sort of blueprint for items--each ScriptableObject representing a certain kind of item--but then use a MonoBehaviour or even a plain old C# class for each copy of that item. Like, if you find a stack of 20 minor healing potions, there would still be only one ScriptableObject that describes what a "minor healing potion" is, but the actual items-in-the-game would just have a shared reference to that ScriptableObject, rather than 20 copies of it.
     
    eses likes this.
  4. FurionStudios

    FurionStudios

    Joined:
    Sep 23, 2020
    Posts:
    4
    Sorry, I'm new to the whole thread stuff, all I want to do is make my slots stackable (Whenever the item is stackable, stack it) so whenever you pick up the same item, the amount on the slot goes up. This part of the code is out of a tutorial I found, but it doesn't work the way I want it to.

    Code (CSharp):
    1. public class Item : ScriptableObject
    2. {
    3.     public string itemName;
    4.     public int id;
    5.     public int amount;
    6.     public Sprite itemThumbnail;
    7.  
    8.     public bool isStackable = false;
    9.  
    10.     public Item(Item item)
    11.     {
    12.         itemName = item.name;
    13.         id = item.id;
    14.     }
    15. }
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Inventory : MonoBehaviour
    6. {
    7.     public List<InventorySlot> slotList = new List<InventorySlot>();
    8.  
    9.     void Start()
    10.     {
    11.  
    12.     }
    13.  
    14.     void Update()
    15.     {
    16.      
    17.     }
    18.  
    19.     public void AddToInventory(Item _item, int _amount)
    20.     {
    21.         for (int i = 0; i < slotList.Count; i++)
    22.         {
    23.             if (_item.isStackable && _item.id == slotList[i].item.id)
    24.             {
    25.                 slotList[i].AddAmount(_amount);
    26.                 return;
    27.             }
    28.             else if(_item.id != slotList[i].item.id)
    29.             {
    30.                 //print("false");
    31.             }
    32.         }
    33.         slotList.Add(new InventorySlot(_item, _amount));
    34.     }
    35. }
    36.  
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class InteractRay : MonoBehaviour
    6. {
    7.     public Camera playerCam;
    8.     public float rayRange = 2f;
    9.  
    10.     public Inventory inventory;
    11.  
    12.     void Start()
    13.     {
    14.      
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         InteractionRay();
    20.     }
    21.  
    22.     public void InteractionRay()
    23.     {
    24.         RaycastHit hit;
    25.  
    26.         //Debug.DrawRay(playerCam.transform.position, playerCam.transform.forward * 2, Color.red, 0.5f);
    27.         if (Physics.Raycast(playerCam.transform.position, playerCam.transform.forward, out hit, rayRange))
    28.         {
    29.             //print(hit.transform.name);
    30.             if (hit.transform.tag == "Item")
    31.             {
    32.                 if (Input.GetKeyDown(KeyCode.F))
    33.                 {
    34.                     var item = hit.transform.GetComponent<GroundItem>();
    35.                     if (hit.transform.GetComponent<GroundItem>().item)
    36.                     {
    37.                         inventory.AddToInventory(new Item(item.item), 1);
    38.                     }
    39.                     //GetComponent<Inventory>().AddToInventory(hit.transform.GetComponent<GroundItem>().item);
    40.                     Destroy(hit.transform.gameObject);
    41.                 }
    42.             }
    43.         }
    44.     }
    45. }
    46.  
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class InventorySlot
    6. {
    7.     public Item item;
    8.     public int amount;
    9.  
    10.     public InventorySlot(Item _item, int _amount)
    11.     {
    12.         item = _item;
    13.         amount = _amount;
    14.     }
    15.  
    16.     public void AddAmount(int Value)
    17.     {
    18.         amount += Value;
    19.     }
    20. }
    21.  
    upload_2020-12-12_14-53-30.png
    This is the warning


    inventory.AddToInventory(new Item(item.item), 1);
    and this is the error in the InteractRay script

    All I want is to stack the Items the moment I pick up an item that has the same ID as the item that's already in the inventory, just change the value of amount to +1. But I'm pretty dumb at this point so any tips could be helpful
     
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,539
    ScriptableObject derived classes can not have a contructor that takes any parameters because you can not create instances with the keyword "new" just like the warning tells you. In order to create a new instance of a ScriptableObject derived class you have to use either the static method
    CreateInstance<Item>()
    or if you want to duplicate an existing instance you can simply use the Instantiate method which seems to be what you want to do anyways.

    So you have two colliding concepts here. On one hand you seem to be used to working with POCOs. On the other hand you use ScriptalbeObjects. Those are two different things. So to solve your issues you either need to turn your Item class into a POCO, then you can use the new keywords as you are used to. Of course when you do that you can no longer store the item as asset in the project. If this is needed / wanted you have to replace the creation of your new item with Instantiate or CreateInstance.

    About the NRE as Antistone already said you have to figure out the exact line where it happens, identify what reference is actually null and then trace back where that reference came from and why it's null. Note that it's a given fact that an object you try to dereference is null, otherwise you don't get a NullReferenceException. Though all this debugging work has to be done directly inside your project. We don't have access to your project so it's your task to figure that out. Writing code is the easy part of programming. Makeing sense of it is the much more difficult and much more important part.