C# 不要破坏加载对象和游戏数据

C# 不要破坏加载对象和游戏数据,c#,json,unity3d,C#,Json,Unity3d,我想在2D游戏进行时使用DontDestroyOnLoad对象保存游戏数据 我有一个GameData类/脚本,它存储诸如health、magicType等值,一个SaveLoad类/脚本,它将GameData类中的当前值保存为Json,还有一个名为PlayerData的空游戏对象,它包含上述两个脚本 目前,我正在使用按钮单击事件在一个场景中保存值。我附加到按钮的对象是PlayerData对象,我在单击事件中使用GameData脚本更改值 但这只适用于第一个场景-我无法附加PlayerData对象

我想在2D游戏进行时使用DontDestroyOnLoad对象保存游戏数据

我有一个GameData类/脚本,它存储诸如health、magicType等值,一个SaveLoad类/脚本,它将GameData类中的当前值保存为Json,还有一个名为PlayerData的空游戏对象,它包含上述两个脚本

目前,我正在使用按钮单击事件在一个场景中保存值。我附加到按钮的对象是PlayerData对象,我在单击事件中使用GameData脚本更改值

但这只适用于第一个场景-我无法附加PlayerData对象并存储其GameData值,因为编辑器中没有PlayerData对象

那么,我如何附加这个位于不同场景中的对象呢?还是我做错了

这是我当前项目的一张照片。

另外,当我保存一个布尔值,然后打开我的Json文件时,该文件是空的。这正常吗?这是我的保存和加载代码:

负载:

private string _filePath;
private static DataService _instance;

public DataService Instance
{
    get { return _instance; }
}

public GameData _gameData;

private void Awake()
{
    DontDestroyOnLoad(gameObject);
}

public void LoadGameData()
{
    _filePath = Path.Combine(Application.persistentDataPath, "GameData1.json");
    string json;
    if (File.Exists(_filePath))
    {
        json = File.ReadAllText(_filePath);
        JsonUtility.FromJsonOverwrite(json, _gameData);
    }
    else
    {
        Debug.Log("File missing.");
    }
}
保存:

public void SaveGameData1()
{
    string json = JsonUtility.ToJson(_gameData);
    _filePath = Path.Combine(Application.persistentDataPath, "GameData1.json");
    if (File.Exists(_filePath))
    {
        File.Create(_filePath).Dispose();
    }
    File.WriteAllText(_filePath,json);
}
编辑:这是我的GameData类的代码:

[Serializable]
    public class GameData : MonoBehavior
    {
        public float Health { get; set; }
    }
数据路径 首先,正如我最近回答的那样,我不会使用persistentDataPath进行开发,而是使用StreamingAssetPath,并在第一次运行应用程序时将文件复制过来

单态模式 我看到您有单例模式的前半部分,但是:您从未为实例赋值。我通常会在酒店里懒洋洋地做这件事,或者像这样醒着

private static DataService instance;
public static DataService Instance
{
    if(instance) return instance;

    instance = FindObjectOfType<DataService>();

    if(instance) return instance;

    // If it wasnt found in the scene create it now
    instance = new GameObject("DataService", typeof (GameData)). AddComponent<DataService>();
    instance._gameData = instance.GetComponent<GameData>();

    DontDestroyOnLoad (instance.gameObject);

    return instance;
}

private void Awake ()
{
    if(instance && instance != this)
    {
        Debug.LogWarning("Another instance of DataService I already in use");
        Destroy(gameObject);
        return;
    }

    if(instance) return;

    instance = this;

    DontDestroyOnLoad (gameObject);

    if(!_gameData) _gameData = GetComponent<GameData>();
}

现在你可以从任何地方打电话

DataService.LoadGameData();
然后访问值,如

DataService.GameData.SomeValue = ...;
按钮 我将创建一个类DataServiceButton,它连接到一个UI.Button,并将自己注册为onClick的监听器

不幸的是,如果没有看到GameData类的代码,就无法回答为什么写入数据后文件为空的问题


请确保您的类型是可序列化的。

根据,请不要在有问题的标题中添加标签。我建议您使用player prefs over json文件将数据保存在Unity中。我在网上读到playerprefs不是很安全,Json是一种方式…@Brandon playerprefs用于保存用户偏好,如音乐音量,而不是存储游戏进度,因为它在每次应用程序更新时都会重置,并且对用户可见和可编辑。Json是一个很好的小步骤,但无论如何,您应该另外使用一些加密;你能添加GameData的代码吗?你确定两个脚本都需要是单行为的吗?谢谢!如果我从GameData类中删除MonoBehavior,那么FromJsonOverwrite是否仍然可以接受?或者我需要更改代码吗?您应该删除{get;set;},而是使用字段而不是属性
DataService.LoadGameData();
DataService.GameData.SomeValue = ...;
[RequireComponent(typeof(UI.Button))]
public class DataServiceButton : MonoBehaviour
{
    public enum ButtonType
    {
        Save,
        Load
    }

    // This is set via the Inspector
    [SerializeField] private ButtonType type;

    // Here you can already reference the according Button component
    [SerializeField] private Button button;

    private void Awake()
    {
        if(!button) button = GetComponent<Button>();

        // Register as callback
        button.onClick.AddListener(HandleClick);
    }

    private void HandleClick()
    {
        switch(type)
        {
            case ButtonType.Load:
                DataService.LoadGameData();
                // OR IF YOU STICK TO THE SINGLETON
                //DataService.Instance.LoadGameData();
                break;
            case ButtonType.Save:
                DataService.SaveGameData();
                // OR ACCORDINGLY WITH SINGLETON
                //DataService.Instance.SaveGameData();
                break;
        }
    }
}