"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 шт):
Попробуйте уменьшить количество ячеек в массиве Из за того, что 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#, у вас пробелы в основах, в частности, обязательно почитайте про создание объектов, про статические классы, структуру, конструктор - это то, с чем необходимо постоянно взаимодействовать.