unity基础3-数据持久化

ScriptableObject

保存常用数据类型,可以在 inspector 窗口中查看,例如
把怪物、玩家的属性保存成 ScriptableObject
《麦田物语》系列中,把物品数据保存成 ScriptableObject 类似下面的做法

using UnityEngine;
using System.Collections.Generic;

[CreateAssetMenu(fileName = "CropData", menuName = "CropData/CropData", order = 0)]
public class CropDataList_SO : ScriptableObject
{
    /// 
    /// 农作物数据库
    /// 
    public List<CropDetails> cropDetailsList;
}

然后就可以在 project 窗口中,右键创建 ItemData
填写数据并使用 public ItemData itemDataList;

PlayerPrefs

下面是 3DRPG 基础系列中《SaveManager.cs》保存玩家数据的例子
保存键值对,但可以配合 JsonUtility 来保存对象

	private void Save(Object data, string key)
    {
        var jsonData = JsonUtility.ToJson(data);
        PlayerPrefs.SetString(key, jsonData);
        PlayerPrefs.SetString(sceneName, SceneManager.GetActiveScene().name);
        PlayerPrefs.Save();
    }
    private void Load(Object data, string key)
    {
        if (PlayerPrefs.HasKey(key))
        {
            JsonUtility.FromJsonOverwrite(PlayerPrefs.GetString(key), data);
        }
    }

再封装一层使用

	public void LoadPlayerData()
    {
        var data = GameManager.Instance.playerStats.characterData;
        Load(data, data.name);
    }

    public void SavePlayerData()
    {
        var data = GameManager.Instance.playerStats.characterData;
        Save(data, data.name);
    }

不同的操作系统有不同的保存路径

文件系统存储数据

使用官方的 JSON 包 Newtonsoft Json
下面的例子是《麦田物语》中,使用 3 个存档条保存数据
使用接口为需要存档功能的不同物体(GUID)拓展存档功能

	public interface ISaveable
    {
        string GUID { get; }
        GameSaveData GenerateSaveData();
        void RestoreSaveData(GameSaveData saveData);
        // 自 C Sharp 9.0 版本后,可以在接口中实现方法
        // 在该接口写一个注册方法
        void RegisterSaveable()
        {
            SaveLoadManager.Instance.RegisterSaveable(this);
        }
    }

获取GUID

using UnityEngine;
[ExecuteAlways]
public class DataGUID : MonoBehaviour
{
    // 挂载在需要存储的物体上,实现存储数据的唯一性
    public string guid;
    private void Awake() {
        if (guid==string.Empty)
        {
            // 16 位长度的字符串
            guid = System.Guid.NewGuid().ToString();
        }
    }
}

读写数据

		private void Save(int index)
        {
            // 保存到哪一条存档位置里
            DataSlot data = new DataSlot();

            foreach (var saveable in saveableList)
            {
                data.dataSlotDict.Add(saveable.GUID, saveable.GenerateSaveData());
            }

            dataSlotList[index] = data;

            // 序列化后写入文件中存储

            // 最终路径
            var resultPath = jsonFolder + "data" + index + ".sav";
            // 带缩进格式去存储 序列化数据
            var jsonData = JsonConvert.SerializeObject(dataSlotList[index], Formatting.Indented);
            if (!File.Exists(resultPath))
            {
                Directory.CreateDirectory(jsonFolder);
            }
            // 写入文件
            File.WriteAllText(resultPath, jsonData);
        }

读取数据

		public void Load(int index)
        {
            currentDataIndex = index;

            var resultPath = jsonFolder + "data" + index + ".sav";

            if (File.Exists(resultPath))
            {
                var stringData = File.ReadAllText(resultPath);

                // 反序列化
                var jsonData = JsonConvert.DeserializeObject<DataSlot>(stringData);

                foreach (var saveable in saveableList)
                {
                    saveable.RestoreSaveData(jsonData.dataSlotDict[saveable.GUID]);
                }
            }
            else
            {
                Debug.LogError("存档文件丢失");
            }

        }

使用接口时,先注册一下,再实现对应的方法即可
public class TransitionManager : Singleton, ISaveable

		void Start()
        {
            ISaveable saveable = this;
            saveable.RegisterSaveable();

            fadeCanvasGroup = FindObjectOfType<CanvasGroup>();
        }

		public GameSaveData GenerateSaveData()
        {
            GameSaveData saveData = new GameSaveData();
            saveData.dataSceneName = sceneName;
            return saveData;
        }
        public void RestoreSaveData(GameSaveData saveData)
        {
            // Debug.Log("重新加载场景");
            sceneName = saveData.dataSceneName;
            // 按照游戏存档,重新加载场景内容
            StartCoroutine(LoadSaveDataScene(sceneName));
        }

你可能感兴趣的:(unity基础,unity,游戏引擎)