Unity简单本地存档系统

这篇具有很好参考价值的文章主要介绍了Unity简单本地存档系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

        本文主要记述一些我在研究Unity简单存档系统时的总结和见闻,纯属个人笔记。

前言涉及到一些本人自己的关于存档系统这一宽泛概念的总结,篇幅较长,如果不感兴趣请直接跳过到后面的脚本环节。

存档系统是绝大多数游戏不可或缺的内容(除了那些刻意为之的游戏)。看了这么多网上有关存档系统的分享,受益匪浅。大致总结了一下我所认为的一个标准的Unity存档系统应该具备的“三要素”:

1.原始数据

2.序列化方法

3.加密方法

        上面三个其实每一个都可以拉出来单独长篇大论,但是现在就先以一整个系统为核心,简单分析一下它们的作用:

1.原始数据:这不废话吗?!存档存的当然是数据!但是关键点其实是如何构建一个好的原始数据,如何让数据易于管理,易于修改,易于存储,易于拓展才是关键因素,好的原始数据可以决定构建整个存档系统的蓝图。因为整个存档系统本身就是为了数据而诞生的。

2.序列化方法:我们在上面提到了存数据是我们存档系统的目的。那么序列化则是达成这种目的途径。在我看来:序列化就是以某种协议或规则,让不同类型的数据变成同一类型以方便数据传输那么应该是哪种类型呢?当然是字节——计算机数据处理的基本单位。

        说点具体的,比如一套数据有诸如”姓名“(string),”生命值“(int),”暴击率“(float)等等许多不同的类型。为了实现它们的写入和读取,我们将它们转换为字节数组的形式或简介表示为字节数组的形式实现统一的管理。但是我怎么知道我取出来和写进去的是不是同一个数据呢?所以序列化方法就此而生。JDK、JSON、XML、Hessian、Kryo、Thrift、Protostuff、FST,二进制等等序列化方法就是人们创造来规范序列化的。下文的简单存储系统是以Json作为序列化方法。

3.加密方法:其实这个要素是可有可无,但是与我个人而言,如果游戏玩家能随意修改数值,那么游戏将会失去很多乐趣,当然除非作者刻意为之。所以我把它将其视作存档系统的重点之一(因为好像也没什么重点了)。对于加密方法其实也是可以细分好多种。但对于今天这篇文章这篇内容,本地加密方法才是重点。如果你打开Json数据文本你就会发现Json的可读性非常高,几乎把你的数据暴露完全。所以最简单的数据加密就是把你的数据以某种方法转化成”一坨大便“。让它的可读性几乎为零,当然你先要记住这种加密方法并能够在需要读取数据的时候解密。下面的存档系统就是用这种简单粗暴的方式。

        好了说了那么多还没到正餐,赶紧看看。

简单存档系统

原始数据

        这个简单存档系统包括了三样东西(除去杂七杂八的设置)

首先是一个叫SaveData的脚本:

using System;

[Serializable]
public class SaveData
{
    public int coin = 0;
}

它对应了存档系统所说的原始数据。当然我并没有让它显得很高大上,毕竟这里仅作演示,顺带一提这里可以不需要[Serializable]标签,因为我们不涉及二进制或XML的序列化。

        这个int coin就是我们要存储的数据。

下面请构建一个类似的场景帮助我们实现存档功能的基本原理。

Unity简单本地存档系统,unity,游戏引擎

number在运行时显示coin。

序列化方法

到这里我们需要开始编写序列化和加密操作。如下所示:

using System;
using System.IO;
using UnityEngine;
using UnityEngine.UI;

public class SaveSystem : MonoBehaviour
{    
    SaveData data = new();
    //获取“我的文档”对应的路径目录
    private string SavePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    //存放存档文件的那个文件夹的名字
    private const string SaveFolder = "MyGame";
    //存档文件名称(这里要全称)
    private const string SaveFileName = "test.txt";

    //声明一个目录信息用来保存路径
    private DirectoryInfo directoryInfo;
    
    private void Awake()
    {
        DontDestroyOnLoad(gameObject);    
        //这里的Path.Combine()用来链接路径,实际上用 SavePath + "/" + SaveFloder 表示也行
        directoryInfo = new DirectoryInfo(Path.Combine(SavePath, SaveFolder));
    }
    //用来增加金币
    public void AddCoin()
    {
        data.coin++;
    }
    //保存
    public void Save()
    {        
        //如果该路径不存在就先将其创建出来
        if (!directoryInfo.Exists) 
        {
            directoryInfo.Create();
        }
        
        string EncryptedData = SaveDataEncryption.EncryInNegation(JsonUtility.ToJson(data));

        File.WriteAllText(Path.Combine(directoryInfo.FullName,SaveFileName),EncryptedData);

    }
    //加载
    public void Load()
    {
        //与上述Save为逆过程        
        string DecryptedData 
        = SaveDataEncryption.DecryInNegation(File.ReadAllText(Path.Combine(directoryInfo.FullName, SaveFileName)));
        data = JsonUtility.FromJson<SaveData>(DecryptedData);

    }

    private void Update()
    {
        GameObject.Find("number").GetComponent<Text>().text = data.coin.ToString();
    }


}

上面的方法与按钮对应。这里我希望读者能自行理解,因为我懒得打这么多字(不是),其实是因为这些都是非常简单的基本操作,重点就在于理解存档方法罢了。

        但我不得不提一些比较隐晦的细节。也是我在敲代码时遇到的问题。

1.类的开头我写了很多字符串,这是为了方便管理可能变换的存放路径。然而说到这个,大家大可不必与我相同,因为比较多的单机游戏的存档文件都存放到了文档(Documents)中,比如骑砍。如果你不知道文档是哪个:

Unity简单本地存档系统,unity,游戏引擎

那现在应该知道了吧,这里只是因为我是中文用户才把Documents自动翻译为文档。事实上路径中还是Documents。点进去你可以发现很多游戏名文件夹,那里就是存放存档文件的地方。

        当然不是所有存档文件都存放在这个位置。你大可以天马行空,把存档文件塞到玩家的系统文件夹(不是)!

2.第二点我想说的是,因为存档这个事情本身就是不太属于游戏引擎的东西,所以Unity本身并没有太多相关API,因此我们需要明白脚本顶上那四个命名空间是用来干什么的。这里我就不多说了,全部方法和属性都可以在微软官方文档中查找到。比较需要记住的是:

刚刚我说的

private string SavePath =

Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

这里用到了System中的Environment类。

和存档方法中的File类则是System.IO的一个类。值得一提的是,这里面的API挺多好玩的,也有很多不同方式实现存档系统,这里我选择了很直接的File类。除此之外还有Stream,StreamWriter,StreamReader等类也提供操作文本文件的方法。但是我使用它们的时候遇到一些问题没有解决,所以改用了File。反正这种C#自带的命名空间还是要有所了解才好啊。

3.在文中使用的序列化方法是Unity自带的JsonUtility,因为操作简单方便适合演示我就拿来用了,还有很多第三方库也可以实现。它们之间的具体区别自己去找资料吧。

4.SaveDataEncryption这个类是自己写的类,用来封装一些加密方法,接下来我们就来具体看一下:

加密方法

using System.Text;

public class SaveDataEncryption
{    
    #region 取反
    public static string EncryInNegation(string json)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(json);
        for (int i = 0; i < bytes.Length; i++)
        {
            bytes[i] = (byte)(~bytes[i]);
        }
        return Encoding.Unicode.GetString(bytes);

    }
    //巧妙的是,取反加密解密正好就是完全相同的过程
    public static string DecryInNegation(string json)
    {
        return EncryInNegation(json);
    }
    #endregion
}

这就是一个简单的加密类,用来存放加密方法,当然你大可以将它写在SaveSystem中。不过因为这个加密方法只是简单示范,所以以后如果有其他加密方法需要记录,那么可以归到统一的一个类,这其实也是代码优化的范畴吧。

就像上面写的那样,我尝试用编码区域来界定不同加密方法之间的范围。这个叫做“取反”的加密方法将Json文本数据转化为字节数组后,对每一个字节取反,最后返回一个取反后的文本。

这是加密前的Json文本:

Unity简单本地存档系统,unity,游戏引擎

这是加密后的Json文本:

Unity简单本地存档系统,unity,游戏引擎

是不是真的变成“一坨大便了”!我们想要的效果实现了,玩家也不能随意修改数据了。

        为了避免大家踩坑,我有必要说清楚Unity自带的这个JsonUtility的编码规则仅支持Unicode(无符号 UTF-8),所以不要尝试在这里切换Encoding的其他编码规则,不然会报错。

最后我们来具体演示一下整个存档系统的实现过程。

存档系统演示

        因为GIF不能上传太大的,我又懒得录视频,就图片叙事吧。

Unity简单本地存档系统,unity,游戏引擎

点击“Give me Money”将金钱加到10。

然后点击“Save”保存数据。

Unity简单本地存档系统,unity,游戏引擎可以在对应的路径上观察到文件已经保存下来了,并且文本已经是“一坨大便”了。

回到Unity重新启动,直接点击可以看到“number”又变回10了。

至此Unity简单本地存档系统为您展示完毕。

结语

        因为一边备考一边钻研这个存档系统,所以考试没考好,研究也没研究出什么。但是收获还是很多,由于是个人的总结笔记,文中出现的任何觉得有问题的点请随时找我。

下面就是我自己对存档系统的总结:

        涉及到的现在这个系统只是一个雏形,而且仅适用于本地,对于数据库端的存储应该截然不同,好在我目前只需要用到这种程度。

        对于进一步对该系统的构建有大致几个可能和设想:

1.更换JsonUtility为其他上限更高的序列化具体方法,或者完善JsonUtility的不足,比如不能存储字典之类的嵌套数据类型。除此之外,存档文件不可能只有一个,文件名称也应不同,捕获异常等也需要添加。

2.对原始数据的处理应该更加普适,现在是以单个脚本的单个唯一实例作为运行时的数据(原始数据),在这种方式下只需要将所有数据堆到,转移到这个实例中去就可以了。但是对于比较复杂的,体量比较大的游戏,还需要存储许多结构复杂的数据,此时这种方式就不适用了,可以尝试以接口的方式实现数据的统一管理(受麦扣老师的启发)。一般而言适用于GJ这样的游戏开发中。

3.对于加密方法应当给予更多选择并且更加完全,像上面那样取反操作稍微破译我想也会暴露出原始数据吧。请自行发挥想象力。当然GJ不会用到加密什么的就是了。

4.这是我第一个从整个系统的角度进行总结记录,而不是以一个两个单一脚本,这样做的优势确实是让我非常有必要了解许多内容,缺点是进度很慢很繁琐。可能以重要程度作为要不要进行系统总结的界限吧。

5.作为初学者,非常需要帮助。

6.应当强制自己每周坚持写点东西,总结收获的同时也回顾了。文章来源地址https://www.toymoban.com/news/detail-796849.html

到了这里,关于Unity简单本地存档系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 游戏思考17:寻路引擎recast和detour学习三:客户端角度学习(unity专题导航系统,阶段三完结)

    游戏思考17:寻路引擎recast和detour学习三:客户端角度学习(unity专题导航系统,阶段三完结)

    1)导航系统作用 帮助角色进行AI智能移动:朝目标移动,绕过障碍物,上下台阶… 2)导航系统包括 ①导航网格(NavMesh):下图的蓝色地形,可以行走的表面 ②导航网格代理组件(NavMesh Agent):模拟人物移动和寻路 ③导航网格障碍物(NavMesh Obstacle):定义物体为障碍物,这样导航网

    2023年04月12日
    浏览(14)
  • 十八、Unity游戏引擎入门

    十八、Unity游戏引擎入门

    1、下载     首先需要下载Unity Hub,下载网址:https://unity.com/cn。     然后在其中下载Unity编辑器并安装,可选择最新版本。     接着需要选择适合的开发环境,例如Android Studio或Xcode,以便进行手机游戏开发。在安装完Unity后,需要根据项目需求下载对应的模块和插件,例

    2024年02月16日
    浏览(50)
  • 使用团结引擎开发Unity 3D射击游戏

    使用团结引擎开发Unity 3D射击游戏

           本案例是初级案例,意在引导想使用unity的初级开发者能较快的入门,体验unity开发的方便性和简易性能。       本次我们将使用团结引擎进行开发,帮助想体验团结引擎的入门开发者进行较快的环境熟悉。      本游戏是一个俯视角度的射击游戏。主角始终位于屏幕

    2024年01月19日
    浏览(48)
  • Unity、UE、Cocos游戏开发引擎的区别

    Unity、Unreal Engine(UE)和Cocos引擎是三个常用的游戏开发引擎,它们在功能和特性上有一些区别。以下是它们之间的主要区别: 编程语言:Unity使用C#作为主要的编程语言,开发者可以使用C#脚本进行游戏逻辑编写。Unreal Engine主要使用C++作为编程语言,但也支持蓝图系统,允许

    2024年02月22日
    浏览(46)
  • Unity vs Godot :哪个游戏引擎更适合你?

    Unity vs Godot :哪个游戏引擎更适合你?

    游戏引擎的选择对开发过程和最终产品质量有着重大影响。近年来,Godot和Unity这两款引擎受到广泛关注。本文将从多个维度对两者进行比较,以期为开发者提供正确的选择建议。 Godot和Unity都有各自的优势,没有绝对的好坏之分。Godot开源免费,上手简单,更适合2D和小型游戏

    2024年01月23日
    浏览(56)
  • 30分钟了解所有引擎组件,132个Unity 游戏引擎组件速通!【收藏 == 学会】

    30分钟了解所有引擎组件,132个Unity 游戏引擎组件速通!【收藏 == 学会】

    🎬 博客主页:https://xiaoy.blog.csdn.net 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN 🙉 🎄 学习专栏推荐:Unity系统学习专栏 🌲 游戏制作专栏推荐:游戏制作 🌲Unity实战100例专栏推荐:Unity 实战100例 教程 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📆 未来很长

    2024年02月11日
    浏览(66)
  • Unity Physics2D 2d物理引擎游戏 笔记

    Unity Physics2D 2d物理引擎游戏 笔记

    2d 材质 里面可以设置 摩擦力 和 弹力 Simulated:是否在当前的物理环境中模拟,取消勾选该框类似于Disable Rigidbody,但使用这个参数更加高效,因为Disable会销毁内部产生的GameObject,而取消勾选Simulated只是禁用。 Kinematic 动力学刚体 动力学刚体不受重力和力的影响,而受用户的

    2023年04月24日
    浏览(43)
  • GODOT游戏引擎简介,包含与unity性能对比测试,以及选型建议

    GODOT游戏引擎简介,包含与unity性能对比测试,以及选型建议

    GODOT,是一个免费开源的3D引擎。本文以unity作对比,简述两者区别和选型建议。由于是很久以前写的ppt,技术原因视频和部分章节丢失了。建议当做业务参考。 GODOT目前为止遇到3个比较重大的机遇,第一个是oprea的合作奖,第二个是用支持c#换来的微软的投资,第三个是虚幻

    2024年02月14日
    浏览(112)
  • Unity和UE4两大游戏引擎,你该如何选择?

    Unity和UE4两大游戏引擎,你该如何选择?

    目录 游戏引擎 2 —— 难易区别 编程语言 3 —— 游戏产品 UE4制作的游戏产品  Unity制作的游戏产品  产品类型 5 —— 资源商店 6 —— 人才需求 平均薪资 总结      Unity和UE4都是游戏引擎,所谓游戏引擎就是集成了复杂功能的游戏开发软件,他们帮我们实现了复杂的底层逻

    2023年04月08日
    浏览(50)
  • Unity 开发人员转CGE(castle Game engine)城堡游戏引擎指导手册

    Unity 开发人员转CGE(castle Game engine)城堡游戏引擎指导手册

    一、简介 2. Unity相当于什么GameObject? 3. 如何设计一个由多种资产、生物等组成的关卡? 4. 在哪里放置特定角色的代码(例如生物、物品)?Unity 中“向 GameObject 添加 MonoBehaviour”相当于什么? 5.Unity子目录相当于什么Assets? 6. 支持哪些模型格式? 7. 支持FBX模型格式吗? 8.

    2024年02月07日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包