Unity类银河战士恶魔城学习总结(P146 Delete Save file-P147 Encryption of save data删除数据和加密数据)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili

教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/

本章节实现了快速删除存档和加密存档

以下是加密前和加密后的对比

SaveManager.cs

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;



//2024.11.25
public class SaveManager : MonoBehaviour
{
    public static SaveManager instance;

    [SerializeField] private string fileName;
    [SerializeField] private bool encryptData;

    private GameData gameData;
    private List<ISaveManager> saveManagers = new List<ISaveManager>();
    private FileDataHandler dataHandler;


    [ContextMenu("Delete save file")]
    private void DeleteSaveData()
    {
        dataHandler = new FileDataHandler(Application.persistentDataPath, fileName, encryptData);
        dataHandler.Delete();
    }

    private void Awake()
    {
        if (instance != null)
            Destroy(instance.gameObject);
        else
            instance = this;
    }

    private void Start()
    {
        dataHandler = new FileDataHandler(Application.persistentDataPath,fileName, encryptData);
        saveManagers = FindAllSaveManagers();

        LoadGame();
    }


    public void NewGame()
    {
        gameData = new GameData();
    }


    public void LoadGame()
    {
        gameData = dataHandler.Load();

        if (this.gameData == null)
        {
            Debug.Log("没有找到存档");
            NewGame();
        }

        foreach (ISaveManager saveManager in saveManagers)
        {
            saveManager.LoadData(gameData);
        }

        
    }


    public void SaveGame()
    {
        foreach(ISaveManager saveManager in saveManagers)
        {
            saveManager.SaveData(ref gameData);
        }

        dataHandler.Save(gameData);
    }


    private void OnApplicationQuit()
    {
        SaveGame();
    }


    private List<ISaveManager> FindAllSaveManagers()
    {
        IEnumerable<ISaveManager> saveManagers = FindObjectsOfType<MonoBehaviour>(true).OfType<ISaveManager>();

        return new List<ISaveManager>(saveManagers);

    }
}

FileDataHandler.cs

Save 方法

  • 功能:将 GameData 数据保存到指定路径的文件中。
  • 核心逻辑
    1. 创建完整路径 :通过 Path.Combine 组合文件夹路径和文件名。
    2. 确保文件夹存在 :调用 Directory.CreateDirectory 确保路径中的文件夹被创建。
    3. 序列化数据 :使用 JsonUtility.ToJsonGameData 对象转为 JSON 格式的字符串。
    4. 加密数据(可选) :如果 encrypDatatrue,调用 EncryptDecrypt 方法加密数据。
    5. 写入文件 :通过 FileStreamStreamWriter 写入数据到文件。
    6. 异常处理:捕获并报告文件操作可能抛出的异常。

Load 方法

  • 功能:从文件中读取数据并反序列化为 GameData 对象。
  • 核心逻辑
    1. 创建完整路径 :和 Save 方法类似,通过 Path.Combine 拼接路径。
    2. 检查文件是否存在 :通过 File.Exists 判断文件是否存在。
    3. 读取数据 :使用 FileStreamStreamReader 读取文件内容。
    4. 解密数据(可选) :如果 encrypDatatrue,调用 EncryptDecrypt 解密数据。
    5. 反序列化 :使用 JsonUtility.FromJson 将 JSON 字符串解析为 GameData 对象。
    6. 异常处理:捕获读取过程中的异常并报告。
cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;

//2024.11.27
public class FileDataHandler
{
    private string dataDirPath = "";//数据文件夹路径
    private string dataFileName = "";//数据文件名

    private bool encrypData=false;//是否加密数据
    private string codeWord = "FuNignNa";//加密密码



    public FileDataHandler(string _dataDirPath, string _dataFileName, bool encrypData)
    {
        dataDirPath = _dataDirPath;
        dataFileName = _dataFileName;
        this.encrypData = encrypData;
        
    }

    public void Save(GameData _data)
    {
        string fullPath = Path.Combine(dataDirPath, dataFileName);


        try
        {
            Directory.CreateDirectory(Path.GetDirectoryName(fullPath));//确保路径中的文件夹被创建

            string dataToStore = JsonUtility.ToJson(_data, true);//将数据转换为json格式

            if (encrypData)
                dataToStore = EncryptDecrypt(dataToStore);//加密数据

            using (FileStream stream = new FileStream(fullPath, FileMode.Create))
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.Write(dataToStore);
                }
            }

        }

        catch (Exception e)
        {
            Debug.LogError("保存数据错误: " + fullPath + "\n" + e);
        }
    }

    public GameData Load()
    {
        string fullPath = Path.Combine(dataDirPath, dataFileName);//找到文件路径
        GameData loadData = null;

        if (File.Exists(fullPath))
        {
            try
            {
                string dataToLoad = "";

                using (FileStream stream = new FileStream(fullPath, FileMode.Open))//打开文件
                {
                    using (StreamReader reader = new StreamReader(stream))//读取文件
                    {
                        dataToLoad = reader.ReadToEnd();//读取文件
                    }
                }

                if (encrypData)
                    dataToLoad = EncryptDecrypt(dataToLoad);//解密数据

                loadData = JsonUtility.FromJson<GameData>(dataToLoad);

            }

            catch (Exception e)
            {
                Debug.LogError("读取数据错误: " + fullPath + "\n" + e);
            }
        }


        return loadData;
    }


    public void Delete()//删除数据
    {
        string fullPath = Path.Combine(dataDirPath, dataFileName);//找到文件路径

        if (File.Exists(fullPath))//如果文件存在就删除s
            File.Delete(fullPath);

    }

    private string EncryptDecrypt(string _data)//加密解密
    {
        string modifiedData = "";//修改后的数据

        for (int i = 0; i < _data.Length; i++)
        {
            modifiedData += (char)(_data[i] ^ codeWord[i % codeWord.Length]);  
        }

        return modifiedData;
    }
}
相关推荐
我好喜欢你~1 小时前
C#---StopWatch类
开发语言·c#
CCCC13101633 小时前
嵌入式学习(day 28)线程
jvm·学习
星星火柴9364 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
小狗爱吃黄桃罐头4 小时前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
NRatel4 小时前
亚马逊S3的使用简记(游戏资源发布更新)
游戏·unity·amazon s3
艾莉丝努力练剑5 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
一阵没来由的风5 小时前
拒绝造轮子(C#篇)ZLG CAN卡驱动封装应用
c#·can·封装·zlg·基础封装·轮子
武昌库里写JAVA6 小时前
JAVA面试汇总(四)JVM(一)
java·vue.js·spring boot·sql·学习
杜子不疼.6 小时前
《Python学习之字典(一):基础操作与核心用法》
开发语言·python·学习
小幽余生不加糖7 小时前
电路方案分析(二十二)适用于音频应用的25-50W反激电源方案
人工智能·笔记·学习·音视频