"NullReferenceException: Object reference not set to an instance of an object" при вызове статической функции

При вызове функции из другого скрипта выдаёт ошибку NullReferenceException

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

public class SaveStars
{
    private static Stars Sm = new Stars();
    private static Stars Load()
    {
        if(PlayerPrefs.HasKey("SaveStars"))
        {
            Sm = new Stars();
            for(int i = 0; i < 100; i++)
                Sm.StarsMas[i] = 0;
            PlayerPrefs.SetString("SaveStars", JsonUtility.ToJson(Sm));
        }
        return JsonUtility.FromJson<Stars>(PlayerPrefs.GetString("SaveStars"));
    }

    private static void Save()
    {   
        PlayerPrefs.SetString("SaveStars", JsonUtility.ToJson(Sm));
    }
    public static void Edit(int Level, int Stars)
    {
        Sm = Load();
        Sm.StarsMas[Level] = Stars;
        Save();
    }

    public static int Get(int Level)
    {
        Sm = Load();       
        return Sm.StarsMas[Level];
    }
}

[Serializable]
public class Stars
{
   public int[] StarsMas = new int[100];
}

Например

if(Value >= EnergyBar.maxValue * 0.75 && SaveStars.Get(Level) < 3)
        {
            for(int i = SaveStars.Get(Level); i < 3; i++)
                Money += 10;
            SaveStars.Edit(Level, 3);

При вызове SaveStars.Get и SaveStars.Edit выдаёт эту ошибку


Ответы (2 шт):

Автор решения: AshenBushi

Попробуйте уменьшить количество ячеек в массиве Из за того, что Player Prefs позволяет хранить в одном сохранении не больше 1Кб, такой большой массив может превышать допустимый объём и вовсе не запускаться

→ Ссылка
Автор решения: Александр ДД

Этот класс не статический:

public class SaveStars

поэтому, если вы обращаетесь к нему как к статическому, это вызывает nullreference.

То есть, это: SaveStars.Edit(Level, 3);

Для компилятора равнозначно этому: null.Edit(Level, 3);

Чтобы решить проблему, у вас есть 3 выхода:

1 возможное решение

Объявить класс статическим:

public static class SaveStars

И обращаться к полям, так как вы обращались.

2 возможное решение

Убрать static у полей:

private Stars Sm = new Stars();
private Stars Load()
{
    if (PlayerPrefs.HasKey("SaveStars"))
    {
        Sm = new Stars();
        for (int i = 0; i < 100; i++)
            Sm.StarsMas[i] = 0;
        PlayerPrefs.SetString("SaveStars", JsonUtility.ToJson(Sm));
    }
    return JsonUtility.FromJson<Stars>(PlayerPrefs.GetString("SaveStars"));
}

private void Save()
{
    PlayerPrefs.SetString("SaveStars", JsonUtility.ToJson(Sm));
}
public void Edit(int Level, int Stars)
{
    Sm = Load();
    Sm.StarsMas[Level] = Stars;
    Save();
}

public int Get(int Level)
{
    Sm = Load();
    return Sm.StarsMas[Level];
}

Затем вместо метода Load(), реализовать конструктор:

public SaveStars()
{
    if (PlayerPrefs.HasKey("SaveStars"))
    {
        Sm = new Stars();
        for (int i = 0; i < 100; i++)
            Sm.StarsMas[i] = 0;
        PlayerPrefs.SetString("SaveStars", JsonUtility.ToJson(Sm));
    }
    return JsonUtility.FromJson<Stars>(PlayerPrefs.GetString("SaveStars"));
}

И удалить вызовы метода Load() из методов Edit() и Get()

Вызывать таким образом:

    SaveStars saveStars = new SaveStars();
    if (Value >= EnergyBar.maxValue * 0.75 && SaveStars.Get(Level) < 3)
    {
        for (int i = SaveStars.Get(Level); i < 3; i++)
            Money += 10;
        saveStars.Edit(Level, 3);
    }

3 возможное решение (самое правильное): Перепилить весь код по-правильному, например, непонятно, за что отвечает SaveStars, он, вроде, и сохраняет, и получает, и загружает звёзды, и изменяет, а по названию можно подумать, что он только сохраняет.. Также, советую почитать книжки по c#, у вас пробелы в основах, в частности, обязательно почитайте про создание объектов, про статические классы, структуру, конструктор - это то, с чем необходимо постоянно взаимодействовать.

→ Ссылка