Search Unity

How can I reference gameObject that other script is attached to?

Discussion in 'Scripting' started by Domacin, Nov 30, 2017.

  1. Domacin

    Domacin

    Joined:
    Nov 30, 2017
    Posts:
    7
    So I am following Brackeys RPG tutorial series and I enabled picking up an item and destroying it but I want to be able to drop it onto ground.

    I want to be able to access gameObject that PickUp script is attached to from script InventorySlot so i can pass is through a method Inventory.Remove(item, locationToDrop, gameObjectToDrop). (currently Inventory.Remove doesn't have all the arguments but that is not important for what i want to achieve with this question).

    In current state I get "NullReferenceException: Object reference not set to an instance of an object"

    Here are codes from 3 scripts:

    1. Inventory

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Inventory : MonoBehaviour {
    7.  
    8. #region Singleton
    9.  
    10.     private void Awake()
    11.     {
    12.         if (instance != null)
    13.         {
    14.             Debug.LogWarning("More than 1 inventory!");
    15.             return;
    16.         }
    17.         instance = this;
    18.     }
    19.  
    20.     #endregion
    21.  
    22.     public delegate void OnItemChanged();
    23.     public OnItemChanged onItemChangedCallback;
    24.  
    25.     public int slots = 18;
    26.  
    27.     public static Inventory instance;
    28.  
    29.     public List<Items> items = new List<Items>();
    30.  
    31.  
    32.     // If not enough slots in inventory returns false
    33.     // If enough returns true
    34.     public bool Add(Items item)
    35.     {
    36.         if (!item.isDefaultItem)
    37.         {
    38.             if (items.Count >= slots)
    39.             {
    40.                 Debug.LogWarning("Not enough slots in inventory");
    41.                 return false;
    42.             }
    43.  
    44.             items.Add(item);
    45.            
    46.             if(onItemChangedCallback != null)
    47.             {
    48.                 onItemChangedCallback.Invoke();
    49.             }
    50.         }
    51.  
    52.         return true;
    53.     }
    54.  
    55.  
    56.     // Removes item from inventory
    57.     public void Remove(Items item, /*Transform dropLocation*/ GameObject objectToDrop)
    58.     {
    59.        Instantiate(objectToDrop);
    60.  
    61.         items.Remove(item);
    62.  
    63.         if (onItemChangedCallback != null)
    64.         {
    65.             onItemChangedCallback.Invoke();
    66.         }
    67.  
    68.         // TODO If item is removed, throw it to ground
    69.     }
    70. }
    71.  

    2. InventorySlot

    Code (CSharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class InventorySlot : MonoBehaviour {
    7.  
    8.     public Button removeButton;
    9.  
    10.     public Image icon;
    11.  
    12.     ItemPickup aaa;
    13.  
    14.     Items item;
    15.  
    16.  
    17.     public void AddItem(Items newItem)
    18.     {
    19.         item = newItem;
    20.  
    21.         icon.sprite = item.icon;
    22.         icon.enabled = true;
    23.  
    24.         removeButton.interactable = true;
    25.     }
    26.  
    27.     public void ClearSlot()
    28.     {
    29.         item = null;
    30.  
    31.         icon.sprite = null;
    32.         icon.enabled = false;
    33.  
    34.         removeButton.interactable = false;
    35.     }
    36.  
    37.     public void UseItem()
    38.     {
    39.         if (item != null)
    40.         {
    41.             item.Use();
    42.         }
    43.     }
    44.  
    45.     public void OnRemoveButton()
    46.     {
    47.         Inventory.instance.Remove(item, aaa.gameObject);
    48.     }
    49.    
    50. }
    51.  



    3. ItemPickup


    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class ItemPickup : Interactable {
    5.  
    6.     public Items item;
    7.  
    8.     public Transform playerLocation;
    9.  
    10.     //**********************************************************************************
    11.  
    12.     public override void Interact()
    13.     {
    14.         base.Interact();
    15.  
    16.         PickUp();
    17.     }
    18.  
    19. //*****************************************************************************
    20.  
    21.     void PickUp()
    22.     {
    23.         Debug.Log("Picking up " + item.name);
    24.  
    25.         bool wasPickedUp = Inventory.instance.Add(item);
    26.  
    27.         if (wasPickedUp)
    28.         {
    29.             Destroy(gameObject);
    30.         }
    31.     }
    32. }
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Does the Items type have a game object (for drop) associated with it?

    It looks like you never assign to 'aaa' so ... that'd be your error.
     
  3. Domacin

    Domacin

    Joined:
    Nov 30, 2017
    Posts:
    7
    My goal is to drop any item from inventory, not just specific ones, so I must be able to access gameObject that has ItemPickup script attached to it.

    What should I Assign aaa to?
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, I don't feel as though I fully understand the system you're using ...

    When you pickup an object, is it still in the 3d world, or just in your inventory?
    If it's just in your inventory, is there data on the inventory item that references what kind of world object it used to be?

    Do my questions make sense? :)

    I don't think we should assign anything to 'aaa' until we figure out what's what & where ;)
     
    Domacin likes this.
  5. Domacin

    Domacin

    Joined:
    Nov 30, 2017
    Posts:
    7
    Oooooohh no!!! I destroy it when i pick it up! Thank you very much for insight!
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    lol.. well, that's not necessarily bad! don't get me wrong, I was just asking.
    Because people do all sorts of different things.

    You could destroy the object, but the inventory class (I think yours is called "Items") -- that could have a reference to a prefab for the world object, and if you "drop" your inventory item (of course droppable only ones), then you could instantiate it with that data**.

    So, don't panic .. lol I was just asking how your game is ;)
     
    Domacin likes this.
  7. Domacin

    Domacin

    Joined:
    Nov 30, 2017
    Posts:
    7
    I wasn't panicking I am just glad that I have a direction to move in now. I spent 5-6 hours on this code last night and wound up with same code as in beginning :(
     
  8. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Fair enough :) Well, look at the idea in my post before this one, too..

    Choose whichever you think sounds better, I guess? :)

    Good luck!
     
  9. Domacin

    Domacin

    Joined:
    Nov 30, 2017
    Posts:
    7
    Ok, thank you for your time :)
     
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Sure, no problem. Take it easy :)
     
  11. Domacin

    Domacin

    Joined:
    Nov 30, 2017
    Posts:
    7
    It works now. I made a main prefab hierarchy that acts as default prefab and i call GameObject.Find from InventorySlot script and i just instantiate it. Thanks again for the idea. :)
     
  12. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Okay, well glad you got it working. :)