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;
    }
}
相关推荐
奔跑的犀牛先生2 小时前
unity学习26:用Input接口去监测: 鼠标,键盘,虚拟轴,虚拟按键
unity
__雨夜星辰__5 小时前
Linux 学习笔记__Day2
linux·服务器·笔记·学习·centos 7
学问小小谢5 小时前
第26节课:内容安全策略(CSP)—构建安全网页的防御盾
运维·服务器·前端·网络·学习·安全
charlie1145141919 小时前
从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(协议层封装)
c语言·驱动开发·单片机·学习·教程·oled
来恩10039 小时前
C# 类与对象详解
开发语言·c#
马船长10 小时前
[BSidesCF 2020]Had a bad day1
学习
黄交大彭于晏10 小时前
三端回链增加截图功能
学习
linwq810 小时前
设计模式学习(二)
java·学习·设计模式
Fhd-学习笔记11 小时前
《大语言模型》综述学习笔记
笔记·学习·语言模型
Dr.勿忘12 小时前
C#面试常考随笔8:using关键字有哪些用法?
开发语言·unity·面试·c#·游戏引擎