Я нахожусь на начальном уровне с единством.

У меня есть функция Load (), которая отключается в OnApplicationPause (false). Он отлично работает, если я заблокирую экран или минимизирую приложение и вернусь к нему. Однако когда я его убиваю, я получаю сообщение об ошибке, и данные не загружаются.

Ниже приведен скрипт, прикрепленный к GameObject "SaveManager".

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

public class SaveManager : MonoBehaviour
{
    public GameObject ZwierzetaGroup;
    public GameObject JedzeniaGroup;
    public GameObject PrzedmiotyGroup;

    public List<GameObject> zwierzeta_sprites;
    public List<GameObject> jedzenia_sprites;
    public List<GameObject> przedmioty_sprites;

    public static DateTime oldDate;

    Camera mainCamera;
    public SaveState saveState;


    void Start()
    {
        mainCamera = Camera.main;
        FillArrays();
    }


    public void Save()
    {
        Debug.Log("Saving.");

        SaveSpriteArray("zwierze", zwierzeta_sprites);
        SaveSpriteArray("przedmiot", przedmioty_sprites);
        SaveSpriteArray("jedzenie", jedzenia_sprites);

        PlayerPrefs.SetInt("pieniazki", saveState.GetPieniazki());

        PlayerPrefs.SetInt("HayAmount", saveState.GetHayAmount());
        PlayerPrefs.SetInt("HayMax", saveState.GetHayMax());
        PlayerPrefs.SetInt("FruitAmount", saveState.GetFruitAmount());
        PlayerPrefs.SetInt("FruitMax", saveState.GetFruitMax());


        //time:
        PlayerPrefs.SetString("sysString", System.DateTime.Now.ToBinary().ToString());

        PlayerPrefs.SetInt("First", 1);
    }

    public void SaveSpriteArray(string saveName, List<GameObject> sprites)
    {
        
        for (int i = 0; i < sprites.Count; i++)
        {
            if (sprites[i].activeSelf)
            {
                PlayerPrefs.SetInt(saveName + i, 1);
            }
            else
            {
                PlayerPrefs.SetInt(saveName + i, 0);
            }

        }

    }

    public void Load()
    {
        Debug.Log("Loading.");

        //wczytanie czasu:
        long temp = Convert.ToInt64(PlayerPrefs.GetString("sysString"));
        oldDate = DateTime.FromBinary(temp);
        Debug.Log("oldDate: " + oldDate);

        //wczytywanie aktywnych sprite'ow
        LoadSpriteArray("zwierze", zwierzeta_sprites);
        LoadSpriteArray("przedmiot", przedmioty_sprites);
        LoadSpriteArray("jedzenie", jedzenia_sprites);

        saveState.SetPieniazki(PlayerPrefs.GetInt("pieniazki"));

        saveState.SetHayAmount(PlayerPrefs.GetInt("HayAmount"));
        saveState.SetHayMax(PlayerPrefs.GetInt("HayMax"));
        saveState.SetFruitAmount(PlayerPrefs.GetInt("FruitAmount"));
        saveState.SetFruitMax(PlayerPrefs.GetInt("FruitMax"));


        mainCamera.GetComponent<UpdateMoney>().MoneyUpdate();
    }

    public void LoadSpriteArray(string saveName, List<GameObject> sprites)
    {

        for (int i = 0; i < sprites.Count; i++)
        {
            if (PlayerPrefs.GetInt(saveName + i) == 1)
            {
                sprites[i].SetActive(true);
            }
            else
            {
                sprites[i].SetActive(false);
            }

        }

    }

    private void FillArrays()
    {
        //find children
        foreach (Transform child in ZwierzetaGroup.transform)
        {
            zwierzeta_sprites.Add(child.gameObject);
        }

        foreach (Transform child in PrzedmiotyGroup.transform)
        {
            przedmioty_sprites.Add(child.gameObject);
        }

        foreach (Transform child in JedzeniaGroup.transform)
        {
            jedzenia_sprites.Add(child.gameObject);
        }
    }
}

Ниже приведен кусок скрипта, прикрепленный к основной камере (вероятно, ошибка). SaveManager GameObject with Script прикреплен к этому в инспекторе. Этот сценарий довольно большой, поэтому я пропущу части, которые мне не подходят.

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

public class ManageEncouters: MonoBehaviour
{
    DateTime currentDate;


    public int First;

    public SaveState saveState;
    public SaveManager saveManager;

    public HayBar hayBar;
    public FruitBar fruitBar;

    public GameObject[] jedzenia_sprites;

    void Start()
    {

    }

    void OnApplicationPause(bool pauseStatus)
    {
        if (!pauseStatus)
        {
            currentDate = System.DateTime.Now;

            //Sprawdzanie czy jest to piersze uruchomienie gry (brak zapisu)
            First = PlayerPrefs.GetInt("First");
            if (First == 0)
            {
                Debug.Log("First time in app.");
                RandomiseAnimals();

                SaveManager.oldDate = currentDate;

                hayBar.SetHayMax(1);
                hayBar.SetHay(0);

                fruitBar.SetFruitMax(1);
                fruitBar.SetFruit(0);

                saveState.SetPieniazki(100);
                this.GetComponent<UpdateMoney>().MoneyUpdate();

            }
            else
            {
                Debug.Log("Not the first time in app.");
                saveManager.Load();

            }

            if (TimeInSeconds(currentDate, SaveManager.oldDate) > 12)
            {
                Debug.Log("It's been more than 12 seconds sience last time.");
                EatFood(currentDate, SaveManager.oldDate); 
                RandomiseAnimals();
            }
            else
            {

                Debug.Log("It's been less than 12 seconds sience last time.");
            }

        }
        if (pauseStatus)
        {
            saveManager.Save();
        }
    }

    private int TimeInSeconds(DateTime newD, DateTime oldD)
    {
        TimeSpan difference = newD.Subtract(oldD);

        int seconds = (int)difference.TotalSeconds;

        return seconds;
    }
}

Ниже я получаю сообщение об ошибке. Я не знаю, как скопировать текст, поэтому это изображение. error screenschot: NullReferenceException: Ссылка на объект не установлена ​​на экземпляр объекта

-2
Proppane 2 Май 2021 в 21:31

1 ответ

Лучший ответ

Я почти уверен, что это проблема времени.

OnApplicationPause

Примечание: MonoBehaviour.OnApplicationPause вызывается при запуске GameObject. Вызов осуществляется после пробуждения . Каждый GameObject будет вызывать этот вызов.

Для меня это звучит так, как будто это может быть вызвано, когда ваш SaveManager еще не инициализирован, в частности mainCamera.

Я думаю, вы уже могли решить проблему, переместив инициализацию в Awake вместо

private void Awake()
{
    mainCamera = Camera.main;
    FillArrays();
}

В общем, мое маленькое правило большого пальца

  • по возможности используйте Awake. В частности, инициализируйте все, где вы не зависите от других скриптов (инициализируйте поля, используйте GetComponent и т. Д.)

  • используйте Start, когда вам нужно уже инициализировать другие скрипты (вызывать методы в других компонентах, собирать и передавать экземпляры некоторых префабов, созданных в Awake, и т. д.)

Это покрывает большинство случаев. Если этого недостаточно, вам нужно будет беспокоиться о порядке выполнения или использовать события.

0
derHugo 2 Май 2021 в 19:17