美文网首页
Unity存档系统(使用JsonUtility)

Unity存档系统(使用JsonUtility)

作者: 全新的饭 | 来源:发表于2024-04-09 15:39 被阅读0次

    说明

    若想存储某对象的数据,则该对象对应的类需继承SaveData。

    SaveData提供如下方法:
    保存:Save
    删除:Delete

    静态类SaveSys提供如下方法:
    载入某项数据:Load。载入时需传入名称,要求所有要存储的对象不能重名。
    存储所有数据:SaveAll
    删除所有数据:DeleteAll

    使用

    1. 可在游戏开始时Load所有继承自SaveData的数据。
    2. 在合适的时机SaveAll或Save特定数据。
    3. 在合适的时机Delete特定数据。Delete后,需自行调用Destroy方法,重新Load该数据(这次Load的本质是创建新存档)。

    具体代码

    SaveSys.cs
    包含SaveData和SaveSys

    using System;
    using UnityEngine;
    
    [Serializable]
    public abstract class SaveData
    {
        public string Name { get; private set; }
    
        public void Init(string name)
        {
            Destroy();
    
            Name = name;
            SaveSys.SaveEvent += OnSave;
            SaveSys.DeleteEvent += OnDelete;
            SaveSys.ShowEvent += OnShow;
        }
        public void Destroy()
        {
            SaveSys.SaveEvent -= OnSave;
            SaveSys.DeleteEvent -= OnDelete;
            SaveSys.ShowEvent -= OnShow;
        }
    
        private void OnSave()
        {
            Save();
        }
        private void OnDelete()
        {
            Delete();
        }
        private void OnShow()
        {
            Debug.Log("存档名称:" + Name);
        }
        public void Save()
        {
            SaveSys.Save(Name, this);
        }
        public void Delete()
        {
            SaveSys.Delete(Name);
        }
    }
    
    public static class SaveSys
    {
        // 存储所有
        public static event Action SaveEvent;
        // 删除所有
        public static event Action DeleteEvent;
        // 显示名称
        public static event Action ShowEvent;
        private static string NameToPath(string name)
        {
            return Application.persistentDataPath + "/" + name + ".txt";
        }
    
        public static T Load<T>(string name) where T : SaveData, new()
        {
            var dataStr = string.Empty;
            var path = NameToPath(name);
            if (System.IO.File.Exists(path))
            {
                System.IO.StreamReader file = System.IO.File.OpenText(path);
                dataStr = file.ReadToEnd();
                file.Close();
            }
    
            T t = null;
            if (dataStr != string.Empty)
            {
                t = JsonUtility.FromJson<T>(dataStr);
            }
            else
            {
                // t = (T)System.Activator.CreateInstance(typeof(T), name);
                t = new T();
                Debug.Log("载入存档数据失败。当前还不存在该存档:" + name + "。创建新存档。");
            }
    
            t.Init(name);
            t.Save();
    
            return t;
        }
        public static void Save<T>(string name, T t)
        {
            string content = JsonUtility.ToJson(t, true);
            var path = NameToPath(name);
    
            if (!System.IO.File.Exists(path))
            {
                // 创建后要主动释放:Dispose
                System.IO.File.CreateText(path).Dispose();
            }
            System.IO.File.WriteAllText(path, content, System.Text.Encoding.UTF8);
            Debug.Log(nameof(SaveSys) + ":保存:" + name);
        }
        public static void Delete(string name)
        {
            var path = NameToPath(name);
            if (System.IO.File.Exists(path))
            {
                System.IO.File.Delete(path);
    
                Debug.Log("删除:" + name);
            }
        }
        public static void SaveAll()
        {
            SaveEvent?.Invoke();
            Debug.Log(nameof(SaveSys) + ":保存了所有!");
        }
        public static void DeleteAll()
        {
            DeleteEvent?.Invoke();
            Debug.Log(nameof(SaveSys) + ":删除了所有!");
        }
        public static void ShowAll()
        {
            ShowEvent?.Invoke();
            Debug.Log(nameof(SaveSys) + ":如上是所有存档数据!");
        }
    }
    

    PlayerData.cs
    SaveData的子类,用于测试

    using UnityEngine;
    
    public class PlayerData : SaveData
    {
        public Vector3 Pos;
    }
    

    SaveTest.cs
    用于测试

    using UnityEngine;
    
    public class SaveTest : MonoBehaviour
    {
        private void Start()
        {
            Init();
        }
    
        private void Update()
        {
            MyUpdate();
        }
    
        private void OnDestroy()
        {
            MyDestroy();
        }
    
        private void Init()
        {
    
        }
    
        private PlayerData _playerData;
        private PlayerData PlayerData
        {
            get
            {
                _playerData ??= SaveSys.Load<PlayerData>(nameof(PlayerData));
                return _playerData;
            }
        }
    
        private void MyUpdate()
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                Debug.Log("存档中的Player位置:" + PlayerData.Pos);
            }
            else if (Input.GetKeyDown(KeyCode.A))
            {
                SaveSys.ShowAll();
            }
            else if (Input.GetKeyDown(KeyCode.B))
            {
                SaveSys.SaveAll();
            }
            else if (Input.GetKeyDown(KeyCode.C))
            {
                SaveSys.DeleteAll();
            }
            else if (Input.GetKeyDown(KeyCode.D))
            {
                PlayerData.Pos = Vector3.one * UnityEngine.Random.Range(0, 100);
                Debug.Log("修改Player位置:" + PlayerData.Pos);
                PlayerData.Save();
            }
        }
    
        private void MyDestroy()
        {
    
        }
    }
    

    相关文章

      网友评论

          本文标题:Unity存档系统(使用JsonUtility)

          本文链接:https://www.haomeiwen.com/subject/qdyfxjtx.html