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

Items not saving because of NullReferenceException

Discussion in 'Scripting' started by TRG_Matthew, Jan 17, 2020.

  1. TRG_Matthew

    TRG_Matthew

    Joined:
    Feb 1, 2017
    Posts:
    1
    Hi! I might have to apologize for the dumb question but I don't really understand why I get this error. Every time I load a shop in my game it gives me an error:
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. ShopController.IsItemBought (SpellPattern spell) (at Assets/Scripts/Unity/ShopController.cs:13)
    3. ShopItem.Start () (at Assets/Scripts/Unity/ShopItem.cs:43)
    4.  
    here's ShopController.cs

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ShopController : PSingleton<ShopController>
    6. {
    7.     private List<SpellPattern> m_boughtSpells = new List<SpellPattern>();
    8.  
    9.     public bool IsItemBought(SpellPattern spell)
    10.     {
    11.         foreach(var el in m_boughtSpells)
    12.         {
    13.             if (el.Equals(spell))
    14.             {
    15.                 return true;
    16.             }
    17.         }
    18.  
    19.         return false;
    20.     }
    21.  
    22.     public void AddNewBoughtItem(SpellPattern item)
    23.     {
    24.         if (!m_boughtSpells.Contains(item))
    25.         {
    26.             m_boughtSpells.Add(item);
    27.             GameManager.Instance.SaveGame();
    28.             GameManager.Instance.LoadGame();
    29.         }
    30.     }
    31.  
    32.     protected override void Load()
    33.     {
    34.         m_boughtSpells = gameData.boughtSpells;
    35.     }
    36.  
    37.     protected override void Save()
    38.     {
    39.         gameData.boughtSpells = m_boughtSpells;
    40.     }
    41. }
    42.  

    and here's start void from ShopItem.cs

    Code (CSharp):
    1.   private void Start()
    2.     {
    3.         anim = tutorialPointer.GetComponent<Animation>();
    4.  
    5.         isBought = ShopController.Instance.IsItemBought(spellPattern);
    6.     }
    7.  
     
  2. Luxgile

    Luxgile

    Joined:
    Nov 27, 2016
    Posts:
    16
    Looks like the element you are getting from the "foreach" is null. Which probably is because either you are adding a null element in "AddNewBoughtItem" or your saving/loading system is messing with it.
     
  3. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,135
    Yep. You really should be checking for null items in the AddNewBoughtItem, Save and Load methods to catch any nulls slipping into the collection as soon as possible.

    Code (CSharp):
    1. public void AddNewBoughtItem([NotNull]SpellPattern item)
    2. {
    3.     if(item == null)
    4.     {
    5.         throw new ArgumentNullException("AddNewBoughtItem called with a null item!");
    6.     }
    7.     ...
    8. }
    9.  
    10. protected override void Load()
    11. {
    12.     m_boughtSpells = gameData.boughtSpells.RemoveNullValues("Bought Spells contained a null item after loading.");
    13. }
    14.  
    15. protected override void Save()
    16. {
    17.     gameData.boughtSpells = m_boughtSpells.RemoveNullValues("Bought Spells contained a null item when saving.");
    18. }
    19.  
    20. public static class ListExtensions
    21. {
    22.     public static void RemoveNullValues<T>([NotNull]this List<T> list, string errorIfNullFound) where T : class
    23.     {
    24.         for(int n = list.Count - 1; n >= 0; n--)
    25.         {
    26.             if(list[n] == null)
    27.             {
    28.                 Debug.LogError(errorIfNullFound);
    29.                 list.RemoveAt(n);
    30.             }
    31.         }
    32.     }
    33. }