0

I'm trying to save and Load on my unity game on a file, I have no problem storing things like highScore, gold etc, but I can't store a list of a class called ObjectShop, I'm getting nullreference error.

I have a code where I can buyItems, they are objects with class ObjectShop, there I have all the information I need.

So when the buton is pressed I'm trying to add to the list the updated object for later store it in to my saveSystem, but getting an error on this line:

SystemDataController.systemDataController.powers.Add(itemListed);

Here is full script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class BuyButton : MonoBehaviour
{
    public int itemId;

    public void BuyItem()
    {
        foreach (var itemListed in ArmorShop.armorShop.items)
        {
            //Can buy the item
            if (itemListed.id == itemId && !itemListed.bought && GameControllerShop.gameControllerShop.RequestGold() >= itemListed.price)
            {
                //Set it to bought
                itemListed.bought = true;
                //Quit the money
                GameControllerShop.gameControllerShop.RemoveGold(itemListed.price);

                //Here I have the error: NullReferenceException: Object reference not set to an instance of an object  
                SystemDataController.systemDataController.powers.Add(itemListed);
                SystemDataController.systemDataController.SaveData();
            }
        }

        ArmorShop.armorShop.UpdateItem(itemId);
    }
}

and that's what I have so far:

GameData.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class GameData
{
    public float gold;
    public float highScore;
    public List<ObjectShop> powers = new List<ObjectShop>();

    public GameData(SystemDataController game)
    {
        highScore = game.highScore;
        gold = game.gold;
        powers = game.powers;
    }
}

SystemDataController.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SystemDataController : MonoBehaviour
{
    public static SystemDataController systemDataController;
    public float gold;
    public float highScore;
    public List<ObjectShop> powers = new List<ObjectShop>();

    private void Awake()
    {
        systemDataController = this;
        LoadData();
    }

    public void SaveData()
    {
        SaveSystem.SaveData(this);
    }

    public void LoadData()
    {
        GameData data = SaveSystem.LoadGame();

        if (data != null)
        {
            gold = data.gold;
            highScore = data.highScore;
            powers = data.powers;
        }
    }
}

EDIT: I have read the link provided from here What is a NullReferenceException, and how do I fix it? and it doesn't talk about my problem, mine its about saving a custom class list on a file and also adding items to a possible null list?

EDIT2: Added object shop:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class ObjectShop
{
    public int id;
    public float price;
    public string name;
    public Sprite itemSprite;
    public bool bought;
    public string description;
    public bool equipped;
}
Sociopath
  • 295
  • 2
  • 14
  • The answer in the [marked duplicate](https://stackoverflow.com/q/4660142/1260204) is pretty much a "how to troubleshoot NRE", a guidebook if you will. Use the advice in that answer to figure out what is causing the NRE in your code – Igor Aug 27 '19 at 15:04
  • @Igor woudln't write on stackoverflow if I didnt try first – Sociopath Aug 27 '19 at 15:21
  • Have you set a breakpoint on the line that causes the issue and discovered what is null? –  Aug 27 '19 at 15:23
  • `ArmorShop.armorShop.items` where is that created? Proper use of classes and a constructor will be your friend here. – Mark Schultheiss Aug 27 '19 at 15:24
  • yes, the object its not null but seems like the list powers isnt instantiate or something, but it has a new List when declared – Sociopath Aug 27 '19 at 15:24
  • You are apparently trying to dereference `systemDataController` before the `Awake()` method has been called. *Something* is null. The NRE doesn't lie. Use your debugger. –  Aug 27 '19 at 15:25
  • @Amy but I can store the gold and highscore without problem, the awake method is being called correctly – Sociopath Aug 27 '19 at 15:28
  • 1
    @Sociopath We cannot debug your code for you. Have you set a breakpoint on the line that causes the issue and discovered what is null? I am not convinced that your analysis is correct, or that you have debugged your code. You don't seem to know what the null object is. Read through the duplicate, it's full of advice on solving this issue. –  Aug 27 '19 at 15:31
  • @Amy yes, powers is null, doesn't this declaration initialize it? public List powers = new List(); – Sociopath Aug 27 '19 at 15:36
  • Yes, but `powers` is also set elsewhere in your code. –  Aug 27 '19 at 15:39
  • 1
    I did see that you decorated a type with `System.Serializable`, do note that most serializers will serialize/deserialize public properties with getter/setters only by default. You are using public fields which is generally frowned upon because it also breaks encapsulation and could also mean that your deserialized type has `null` values for these fields. – Igor Aug 27 '19 at 15:54
  • Im a bit newbie on C# and can't understand why float and strings works fine but not a list, they both are initialitzed so I don't get it – Sociopath Aug 27 '19 at 16:20
  • Looks like `LoadGame` is returning a `GameData` with a null `powers` field. Please include your definition for `ObjectShop`. If `ObjectShop` can't be (de)serialized, that's probably causing deserialization to give up and overwrite the empty list with a null one. – Ruzihm Aug 27 '19 at 16:38
  • `can't understand why float and strings works fine but not a list...` - In the code you have shown there are 2 floats and a generic list. A float is a value type and will always be initialized to 0 by default, the list is a reference type and will always be initialized to `null` by default. That is why accessing the list would throw an NRE @Sociopath. – Igor Aug 27 '19 at 17:13
  • @Ruzihm I added object shop – Sociopath Aug 27 '19 at 18:01
  • 1
    I recommend you take a step back and learn how to debug your code at run time. Here are a few of the many resources available: [Navigate through code with the Visual Studio debugger](https://docs.microsoft.com/en-us/visualstudio/debugger/navigating-through-code-with-the-debugger), [Learn to debug C# code using Visual Studio](https://docs.microsoft.com/en-us/visualstudio/get-started/csharp/tutorial-debugger), and [Debugging C# Code in Visual Studio | Mosh](https://youtu.be/u-HdLtqEOog). put some break points on assignments so you can figure out at what point a null value is being assigned. – Igor Aug 27 '19 at 18:11

0 Answers0