Unity3D游戏序列化以及新版本发布

Unity3D-游戏序列化 序列化 就是把一个内存对象变为与地址无关的可传输的数据格式,通常是文本格式;反序列化反之。一般情况下,对象序列化指把一个对象用 XML,YAML 或 json 文本表示。 尽管 Unity 场景文件是 yaml 格式的,但并没有提供运行时内置支持。Unity 已内置 json 支持。 现在我要对我之前写的飞碟游戏进行初步的序列化。 实现序列化后,游戏版本信息以及每个关卡的规则信息都选择json文 阅读详情

序列化技术:
序列化 就是把一个内存对象变为与地址无关的可传输的数据格式,通常是文本格式;反序列化反之。

一般情况下,对象序列化指把一个对象用 XML,YAML 或 json 文本表示。 尽管 Unity 场景文件是 yaml 格式的,但并没有提供运行时内置支持。

Unity 已内置 json 支持。
在U3D中使用Serializable标签来标识可序列化对象

[Serializable]
public class MyClass
{
    public int level;
    public float timeElapsed;
    public string playerName;
}

在一个 monoBehavior 中,添加上述类,[Serializable]标签,说明这个类可以被序列化。

U3D中内置了JsonUtility类,用于支持对象的序列化与反序列化,这个类主要包括三个方法

  • FromJson 用 Json 数据实例化一个新对象
  • FromJsonOverwrite 用 Json 数据重新赋值一个对象
  • ToJson 将对象变成一个字符串

下面具体讲一下利用序列化技术发布新的游戏版本

我们采用之前做得飞碟设计游戏作为例子
每次开始游戏之前会读取远程控制目录的游戏版本文件,如果发现与当前的版本不一致就会更新游戏,如果游戏版本没变,则会进入到上次退出游戏时的状态,能够看到上次退出时的分数和轮数

首先是远程控制目录,我设置的是D:\UnityVersionData文件夹
每个版本的文件夹下面有多个json文件,包括一个game_info文件和多个disk_level文件
版本文件

game_info文件包含游戏的版本号以及当前总的轮数:
disk_info文件包括每一轮游戏的各种设置参数,例如射出的飞碟数,飞碟颜色,初速度,入射角度等

新建C#脚本,用于版本控制
声明用于序列化的对象

[Serializable]
    public class GameInfo : System.Object {
        public string version;
        public int totalRound;
    }

    [Serializable]
    public class LevelInfo:System.Object {
        public int round;
        public int UFO_total_num;
        public string color;
        public float disk_scale;
        public float speed;
        public float lanuch_position_Y;
        public float lanuch_angle;
    }

这两个对象分别对应json文件里的对象(注意,这里的对象类型必须是JsonUtility能够解析的对象类型,主要是各种基础类型,如果有类成员变量,需要将这个类单独进行序列化,不然无法解析)

声明一个版本管理类,使用单例模式,用于管理版本信息

public class DictManager : System.Object {
        private static DictManager _instance;
        private static readonly string gameversion = "version";
        private static readonly string gameround = "totalRound";
        //最多10轮
        private static readonly string[] disk_level = new string[]{
  
  "disk_level_1", "disk_level_2", "disk_level_3", 
            "disk_level_4", "disk_level_5", "disk_level_6", "disk_level_7", "disk_level_8", "disk_level_9", "disk_level_10"};
        private static readonly string currentRound = "currentRound";
        private static readonly string currentScore = "currentScore";

        public static DictManager getInstance() {
            if (_instance == null)
                _instance = new DictManager ();
            return _instance;
        }

        //保存版本信息
        public void setVersion(string version) {
            PlayerPrefs.SetString (gameversion, version);
        }

        public string getVersion() {
            return PlayerPrefs.GetString(gameversion, "none");
        }

        //保存总的游戏轮数
        public void setTotalGround(int totalRound) {
            PlayerPrefs.SetInt (gameround, totalRound);
        }

        public int getTotalRound() {
            return PlayerPrefs.GetInt (gameround, 0);
        }

        //保存当前轮数的游戏信息
        public void setLevelInfo(int index, string text) {
            PlayerPrefs.SetString (disk_level [index], text);
        }

        public void cleanLevelInfo(int index) {
            while (index < 10 && PlayerPrefs.HasKey (disk_level [index])) {
                PlayerPrefs.DeleteKey (disk_level [index]);
                index++;
            }
        }

        public string getLevelInfo(int index) {
            return PlayerPrefs.GetString (disk_level [index], "none");
        }

        //保存当前轮数
        public void setCurrentRound(int Round) {
            PlayerPrefs.SetInt (currentRound, Round);
        }

        public int getCurrentRound() {
            return PlayerPrefs.GetInt (currentRound);
        }

        //保存当前分数
        public void setCurrentScore(int Score) {
            PlayerPrefs.SetInt (currentScore, Score);
        }

        public int getCurrentScore() {
            return PlayerPrefs.GetInt (currentScore);
        }

    }

这个管理类中使用了PlayerPrefs类,他的作用是保存游戏Session之间的数据,从代码中可以发现,这个其实就是一个字典,他以key-value的方式持久化数据,一般来说,这个类适合用来存储与现场恢复相关的数据,类似于web开发中的session和cookie,关于PlayerPrefs类的具体用法可以参考
http://docs.unity3d.com/ScriptReference/PlayerPrefs.html

注意到这里使用了一个单例类来管理这个字典,并且字典是注入式的,这样就很好的解决了字典的同步问题,也降低了代码的耦合度,这里采用了OO设计原则

接下来是关于json文件加载,这里使用MonoBehavior的类来加载文件
这里需要使用WWW类,这是一个万能类,支持HTTP,HTTPS, file, jar:file等协议,由于加载文件属于IO操作(如果使用HTTP等协议还可能是网络操作),所以会阻塞当前线程,显然我们不能在主线程里面加载,但是U3D又不能像JAVA一样支持多进程多线程,那怎么办呢?当然是使用协程了!协程可以显式的调用中断,我们只要在加载文件出设置中断就可以了,直到指定的事件发生,由 ReActor 调度程序从当前断点继续执行。
关于U3D中的协程更多知识可以参考
http://docs.unity3d.com/Manual/Coroutines.html
这里就不多说了,关于协程的原理就直接google吧。。。。。资料很多,总的来说协程就是一个伪线程,用来模拟线程的。


        
Unity进阶】深度解析Serializable、SerializeField与SerializeReference的实战应用与性能优化 本文深度解析Unity中`[Serializable]`、`[SerializeField]`和`[SerializeReference]`三大序列化特性的实战应用与性能优化。通过RPG游戏开发实例,详细讲解如何利用这些特性实现数据持久化、多态序列化,并分享性能陷阱的解决方案,帮助开发者提升Unity项目的开发效率和运行性能。 阅读详情

相关推荐

Unity中的序列化和反序列化

序列化是指把对象转换为字节序列的过程,而反序列化是指把字节序列恢复为对象的过程。序列化最主要的用途就是传递对象和保存对象在Unity中保存和加载、prefab、scene、Inspector窗口、实例化预制体等都使用了序列化与反序列化。...

L的博客 7928

Unity-SerializableDictionary:Unity的可序列化字典类

序列化字典 Unity的可序列化字典类。 Unity无法序列化标准字典。 这意味着它们将不会在检查器中显示或编辑,并且不会在启动时实例化。 一个经典的解决方法是将键和值存储在单独的数组中,并在启动时构造字典。 该项目提供了一个通用的字典类及其可解决此问题的自定义属性抽屉。 产品特点 它继承自Dictionary<TKey> 它实现了CopyFrom(IDictionary<TKey>)方法来帮助分配常规字典中的值 您可以统一使用任何可序列化的类型作为键或值。 可以在检查器中对其进行编辑,而无需实现自定义编辑器或属性抽屉。 检查器将处理无效的字典键,例

Unity3D游戏开发之游戏读/存档功能在Unity3D中的实现

大家好,我是秦元培,欢迎大家关注我的博客。近期博客的更新频率基本直降到冰点,因为这段时间实在是忙得没有时间来写博客了。今天想和大家分享的内容是RPG游戏游戏存档的实现,因为最近在做一个RPG游戏的项目,所以遇到这个问题就随时记录下来,在对知识进行总结的同时可以将这种思路或者想法分享给大家,这是一件快乐而幸运的事情。我讨厌写按部就班的技术教程,因为我觉得学习是一种自我的探索行为,如果一切都告诉你了,探索的过程便

素履独行 | 元培的个人博客 4万+

.NET 中的对象序列化

.NET 中的对象序列化Piet ObermeyerMicrosoft Corporation2001 年 8 月摘要:为什么要使用序列化?最重要的两个原因是:将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本;按值将对象从一个应用程序域发送至另一个应用程序域。例如,序列化可用于在 ASP.NET 中保存会话状态,以及将对象复制到 Windows 窗体的剪贴板中。它还可用于按值将对...

weixin_34365417的博客 550

Unity C# 类的序列化 [Serializable] 是怎么定义的?

1. 定义自己的Attribute。 在使用Unity开发的时候。时常会用到 [Serializable] 特性来序列化处理一个类。然后想着自己也定义一个 Attribute来管理自己代码。 可以看到[Serializable]代码如下: using System.Runtime.InteropServices; namespace System { [AttributeUsage(At...

Edwin Lee的博客 2653

Unity 中 的Serializable 和 SerializeField

unity知识点

weixin_50702814的博客 5321

深入Unity序列化

序列化和持久化是游戏开发入门后绕不开的点。本文以Unity引擎的游戏开发为例讲讲遇到的坑和经验,适用于客户端开发。

Speculator_m的博客 1521

Unity3D——游戏序列化

说在前面     序列化是为了将对象存储(或传输)到内存、数据库或文件中,把对象状态转化为一组字节的过程。换句话说:就是如何保存对象并恢复其状态以供后续使用。现在的游戏一般都离不开序列化,特别是一些大型游戏,因为游戏本身就非常大,每次版本更新就去重装一次显然不现实。而游戏系列化就能很好的解决这个矛盾,通过比对服务器上的文本数据来判断玩家是否需要更新。 实现     以之前写过的一个简

keep studying 3748

Unity3D 游戏序列化发布

在之前的作业中做了一个打飞碟的小游戏。这次作业是修改这个游戏使之通过从json文件中读取一些设置数据。事实上,在之前那个作业中,我将飞碟的数据分离出来放在DiskData这个类中。在这个类里面用数组(当时初学C#还不清楚C#中的List用法)存放每一轮有多少飞碟以及每个飞碟的颜色、大小、初始位置、发射速度和发射时间。那个代码放在下面,请不要笑。不清楚当时我是怎么想的,为什么不单独用个类将属性组织在

gunnerczh的博客 476

游戏大厂为何偏爱英文好的程序员?

游戏大厂对程序员英文阅读能力的重视程度超乎想象。从UE5文档到Unity更新,从GitHub开源项目到GDC技术白皮书,全球游戏开发的核心技术资料几乎都以英文呈现。大厂面试常设英文文档速读考题,日常开发中能否直接查阅StackOverflow原帖或Reddit技术讨论,直接决定了问题解决效率和创新能力。会英文的程序员能率先掌握前沿技术,参与国际项目协作;而依赖中文二手资料的开发者往往落后行业半年。这不仅关乎个人成长速度,更是大厂筛选人才的重要分水岭——英文阅读能力就是打开全球技术宝库的钥匙。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 1530

使用CSDN-markdown编辑器入门

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Ma...

大米饭 3433

Unity 序列化字典(SerializableDictionary)

Inspector面板上不能序列化字典很不方便,于是自己写了一个。

qq_41916689的博客 1791

unity知识】Serializable、SerializeField 和SerializeReference如何序列化数据和区别

Unity中的[Serializable]、[SerializeField]和[SerializeReference]是三个重要的序列化属性,各自有不同的应用场景。[Serializable]用于标记自定义类、结构体或枚举,使其可被Unity序列化;[SerializeField]则强制序列化私有或受保护字段,使其在Inspector面板可见;[SerializeReference]支持多态对象的序列化,适用于抽象类或接口字段存储子类实例的情况。三者主要区别在于存储方式、适用类型和对多态的支持程度,开发者应

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2155

unity3d 序列化Serializable

转: 常常看说序列化,说什么发消息要序列化,存数据也需要序列化。今天就看了看这个到底是什么东西。 是什么 序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。简单的说就是把对象转换成字节然后到内存中,数据库中或者是文件中的一个过程。 过程   再通俗点讲就是学习武功时候,师傅给徒弟说武功口诀...

zebin的博客 5717

Unity序列化 Serializable 和 SerializeField

Serialize序列化功能: Unity3D 中提供了非常方便的功能可以帮助用户将成员变量在Inspector中显示,并且定义Serialize关系; 简单的说,在没有自定义Inspector的情况下所有显示在Inspector 中的属性都同时具有Serialize功能; 换句话说,就是你在Inspector看到什么,保存游戏的时候,这些值就会被保存成二进制文件; Serializa...

子不语的博客 2315

Unity API(二) ------ Serializable(序列化)

   官方API地址: https://docs.unity3d.com/ScriptReference/Serializable.html 对于Serializable,博主一直是一知半解的,虽然大致知道是什么意思,但是就是不知道为何要用这个,因此翻译下官方文档,希望能理解的更加透彻 描述: The Serializable attribute lets you embed a clas...

千喜 1743

Unity之Serialized序列化:从原理到实践

Unity开发中,序列化(Serialization) 是贯穿整个开发流程的核心技术。无论是游戏对象的持久化存储、Inspector面板的变量显示,还是跨平台数据交换,都离不开序列化的支持。对于编辑器扩展开发而言,深入理解序列化机制更是实现自定义工具和高效数据管理的关键。

我是一个热爱游戏开发的Unity程序员,专注于使用Unity引擎创建创新和高效的游戏项目。在我的博客中,我分享Unity开发中的实用技巧、解决方案和优化方法,涵盖从基础入门到高级技术的各个方面。我喜欢探索新技术,持续学习,并与大家一起成长。希望我的分享能帮 2338

关于Unity3D的[Serializable]的一些自我见解

官方解释: 翻译: 描述 可以序列化类或结构。 若要启用序列化,请应用[序列化]属性。有关序列化的更多信息,请参见脚本序列化。注:只能序列化非抽象的非一般自定义类。 自我见解: 就是Unity提供的一个类似于收纳器的便捷式使用方法,本质上不过就是用一个类来代替一些字段让编辑器编辑,也就是归类一些用在一起字段,归在于一个类里面 ...

weixin_45022355的博客 2617
上一篇: ## Unity3D实现粒子光环效果
datealive
博客等级 码龄11年 2粉丝 2原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值