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

Object Passed and Present... But Gives Null Reference

Discussion in 'Scripting' started by Malleck666, Nov 9, 2016.

  1. Malleck666

    Malleck666

    Joined:
    Jan 9, 2015
    Posts:
    235
    I have a simple inventory system that updates each time a new item is equipped. It removes all the UI elements and updates the equipped view to reflect the changes using a prefab as follows...

    Code (CSharp):
    1. public void UpdateEquipped()
    2.      {
    3.          if (Player.equipped.Length > 0)
    4.          {
    5.              foreach(Item i in Player.equipped)
    6.              {
    7.                  if(i != null)
    8.                  {
    9.                      GameObject icon = Instantiate(invIcon) as GameObject;
    10.                      icon.GetComponent<InventoryIcon>().item = i;
    11.                      icon.GetComponent<InventoryIcon>().isInventory = false;
    12.                      icon.transform.SetParent(holder.transform);
    13.                      icon.transform.localPosition = new Vector3(icon.transform.localPosition.x, icon.transform.localPosition.y, 0);
    14.                      icon.transform.localScale = Vector3.one;
    15.                  }
    16.              }
    17.          }
    18.      }
    When clicked, the inventory item equips itself as follows...

    Code (CSharp):
    1. void EquipFromInventory()
    2.      {
    3.          Player.equipped[item.slotIndex] = item;
    4.          LoadEquipped loadEquipped = GameObject.FindObjectOfType<LoadEquipped>();
    5.          loadEquipped.ClearEquipped(false);
    6.      }
    Now the issues is that I have a tooltip that shows up when hovering over and item anywhere in the inventory. That works fine until I equip an item, then the equipped items no longer show their tooltip but instead cause a null reference error. This is how the tooltip is called...

    Code (CSharp):
    1. public void OnPointerEnter(PointerEventData eventData)
    2.      {
    3.          if (!tooltipvisible)
    4.          {
    5.              Vector3 loc = gameObject.transform.position;
    6.              if (item != null)
    7.              {
    8.                
    9.                  Item i = item;
    10.                  tooltip.ShowToolTip(i, loc);
    11.                  tooltipvisible = true;
    12.              }
    13.          }
    14.      }
    and the tooltip method is...

    Code (CSharp):
    1. public void ShowToolTip(Item item, Vector3 pos)
    2.      {
    3.          if (item != null)
    4.          {
    5.              Debug.Log("Showing tooltip for " + item.itemName);
    6.              Item _item = item;
    7.              Debug.Log(_item.itemName + " Object Found");
    8.              nameLabel.text = _item.itemName;
    9.              nameLabel.color = rarityColour[_item.rarity];
    10.              slotLabel.text = _item.slot;
    11.              staminaLabel.text = "+" + _item.stamina + " Stamina";
    12.              strengthLabel.text = "+" + _item.strength + " Strength";
    13.              agilityLabel.text = "+" + _item.agility + " Agility";
    14.              intelligenceLabel.text = "+" + _item.focus + " Focus";
    15.              if (_item.stamina == 0)
    16.              {
    17.                  staminaLabel.gameObject.SetActive(false);
    18.              }
    19.              else
    20.              {
    21.                  staminaLabel.gameObject.SetActive(true);
    22.              }
    23.              if (_item.strength == 0)
    24.              {
    25.                  strengthLabel.gameObject.SetActive(false);
    26.              }
    27.              else
    28.              {
    29.                  strengthLabel.gameObject.SetActive(true);
    30.              }
    31.              if (_item.agility == 0)
    32.              {
    33.                  agilityLabel.gameObject.SetActive(false);
    34.              }
    35.              else
    36.              {
    37.                  agilityLabel.gameObject.SetActive(true);
    38.              }
    39.              if (_item.focus == 0)
    40.              {
    41.                  intelligenceLabel.gameObject.SetActive(false);
    42.              }
    43.              else
    44.              {
    45.                  intelligenceLabel.gameObject.SetActive(true);
    46.              }
    47.              if (_item.effectText == "")
    48.              {
    49.                  effectLabel.gameObject.SetActive(false);
    50.              }
    51.              else
    52.              {
    53.                  effectLabel.gameObject.SetActive(true);
    54.              }
    55.              tooltip.SetActive(true);
    56.              tooltip.transform.position = pos;
    57.          }
    58.          else
    59.          {
    60.              Debug.Log("No Item Passed");
    61.          }
    62.      }
    As I said, it shows the first time around and anywhere else in the game but after equipping an item and renewing the in game icons, an error is thrown. I have debugged at various points and the item still exists right up until it needs to add the name to the nameLabel. The nameLabel object is present and assigned in the inspector and is still there during run time. The crazy thing is that the label properties to update the changes to the text component.

    Thank you in advance - this is giving me a serious headache.
     
  2. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    897
    I think you're focusing on the wrong variable. my bet is its not the Item. but nameLabel thats null.
     
  3. Malleck666

    Malleck666

    Joined:
    Jan 9, 2015
    Posts:
    235
    I thought that too, but it works before the equipment slots are updated. It continues to work for the inventory but not the equipped slots. They are all the same prefab too. The label is still assigned in the inspector.
     
  4. vothka

    vothka

    Joined:
    Mar 27, 2015
    Posts:
    59
    you provided the code but not the exception (message) - it pretty much tells you where your stuff explodes
     
  5. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    897
    from the code you provided you've debugged Item.itemName, but not nameLabel. if Item really was null then it would have nullref'd on the debug line.

    nameLabel may have been set when the slots were updated, but you're not evaluating it inside the ShowTooltip call. and the code you've provided doesn't actually show us where nameLabel was working while the slots were updated. at some point you are either setting/losing the reference for the namedLabel, or showToolTip is referring to a different instance of nameLabel that was never set.

    is nameLabel a field, or a property? where is it set, and what object is it set to in relation to itself?
     
  6. Malleck666

    Malleck666

    Joined:
    Jan 9, 2015
    Posts:
    235
    The error is this...

    "NullReferenceException: Object reference not set to an instance of an object
    Tooltip.ShowToolTip (.Item item, Vector3 pos) (at Assets/Resources/Scripts/Tooltip.cs:37)
    InventoryIcon.OnPointerEnter (UnityEngine.EventSystems.PointerEventData eventData) (at Assets/Resources/Scripts/InventoryIcon.cs:32)
    UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerEnterHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:24)
    UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerEnterHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
    UnityEngine.EventSystems.EventSystem:Update()"

    It points to the line...
    Code (CSharp):
    1. nameLabel.text = _item.itemName;
    For some reason, the connection with the Text component nameLabel is being lost. It is, however, still visible in the hierarchy and still set in the inspector.
     
  7. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    897
    When you equip you remove all UI, does that mean you destroy the text component? If not then what does the code for this line do?
    Code (CSharp):
    1. loadEquipped.ClearEquipped(false);
     
  8. Malleck666

    Malleck666

    Joined:
    Jan 9, 2015
    Posts:
    235
    Code (CSharp):
    1. public void ClearEquipped(bool doesUpdate)
    2.     {
    3.         foreach (Transform child in holder.transform)
    4.         {
    5.             child.GetComponent<InventoryIcon>().DestroySelf();
    6.         }
    7.  
    8.         if (doesUpdate)
    9.         {
    10.             UpdateEquipped();
    11.         }
    12.     }
    ..and the DestroySelf() method is simply...

    Code (CSharp):
    1. public void DestroySelf()
    2.     {
    3.         Destroy(gameObject);
    4.     }