• 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
    {
        /// <summary>
        /// 农作物数据库
        /// </summary>
        public List<CropDetails> cropDetailsList;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后就可以在 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);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    再封装一层使用

    	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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

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

    文件系统存储数据

    使用官方的 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);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    获取GUID

    using UnityEngine;
    [ExecuteAlways]
    public class DataGUID : MonoBehaviour
    {
        // 挂载在需要存储的物体上,实现存储数据的唯一性
        public string guid;
        private void Awake() {
            if (guid==string.Empty)
            {
                // 16 位长度的字符串
                guid = System.Guid.NewGuid().ToString();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    读写数据

    		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);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    读取数据

    		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("存档文件丢失");
                }
    
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    使用接口时,先注册一下,再实现对应的方法即可
    public class TransitionManager : Singleton<TransitionManager>, 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));
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    van-uploader上传图片报错Invalid handler for event “load“(在uniapp编译)
    机器学习5数据归一化Feature Scaling
    React@16.x(33)动画(上)
    python实现简单的神经网络,python实现神经网络算法
    金九银十投递:美团、滴滴、360,面经回馈与经验分享(附学习路线+思维导图+刷题指南)
    小红书母婴行业文案怎么写,创作方向有哪些?
    高质量实时渲染笔记
    LeetCode_前缀和_困难_862.和至少为 K 的最短子数组
    maven 更改版本号
    android 禁止拖动桌面时钟小组件
  • 原文地址:https://blog.csdn.net/qq_42534809/article/details/125457463