【游戏技术群】959392658  【游戏出海群】12067810
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

教程分享

关注:797

当前位置:游戏蛮牛 技术专区 教程分享

查看: 957|回复: 6

[入门教程] unity入门教程_如何自制简易的游戏存档系统

[复制链接]  [移动端链接]
4四处流浪
338/500
排名
7521
昨日变化
7

50

主题

61

帖子

338

积分

Rank: 4

UID
241596
好友
2
蛮牛币
836
威望
0
注册时间
2017-9-5
在线时间
55 小时
最后登录
2018-5-15
发表于 2018-1-8 17:27:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
  本文将为大家分享如何在Unity中实现简单的游戏存档系统,其中不会包含太多实际的代码,仅介绍在制作过程中需要考虑与解决的问题。该系统由一个学生团队为他们的首款商业游戏《Spirit》的原型开发,虽然简单,但其功能却很完善,也很容易扩展到其它需要保存状态的游戏中使用。
  Unity提供了PlayerPrefs来持久化保存游戏状态与数据,但不支持序列化Transform。C#也有大量的文件IO操作选项,但没有提供自动识别对象的方法。下面为大家介绍如何自定义永久性数据存储系统,首先编写一些简单的可序列化的数据结构来存储基本信息(如Transform等),将每个对象与其ID关联,然后将数据写入文件以供再次读取来恢复游戏状态。
  

  第一步是选择生成对象ID的方法,基于创建时间生成的Hash值就很适合用作ID,但C#已经提供了GUID类可用于生成唯一的字符串:
  id = System.Guid.NewGuid().ToString();
  下面需要创建一个全局管理器类,来将ID与对应的对象进行关联。这个管理器就是一个单例类,带有几个用于查询键值的容器(C#中可能使用Dictionary结构)。还可以根据实际项目需求在Awake函数中添加一些基本的初始化与设置操作。如果有需要,还可以更新脚本执行顺序以确保管理器要先于ID生成脚本执行。另外,最好添加两个查找函数,一个用于将ID映射到实例ID(用于检查重复),另一个用于将ID直接映射到GameObject(用于加载文件时根据ID查找对象)。
  ID脚本需要在对象创建时自动生成ID,并在运行期间保持不变。编写脚本时要注意以下几个关键点:
  将ID定义为公共的String类型变了,以便Unity在保存并重新加载场景时,ID可以与对象一起被永久保存。可以利用Unity属性在检视视图中以只读方式显示变量值,以避免被误操作。
  如果ID为空或者无效,需要在Awake函数中生成ID并在管理器中注册此ID。
  在OnDestroy函数中从管理器中注销,以免后续遍历列表时出现空指针。
  可以通过检测对象的实例ID与管理器中“记录”的自定义ID是否一致,来判断键值是否“有效”,以避免出现重复。如果不一致,就重新生成自定义ID。为什么这样呢?如果用ID实例化预制件,或是复制一个带有ID的GameObject,Unity也会复制原有的唯一ID,并且无法在Awake函数或其它地方分辨是否出现重复ID。而如果设置得当,管理器会在文件中记录ID,所以只要在查询函数中查看键值是否有效,就可以解决该问题。
  最后,为ID脚本及管理器脚本添加[ExecuteInEditMode]标签,确保在编辑场景时脚本能正常运行。
  正确设置好管理器与ID脚本后,只需简单地将ID脚本添加到任意需要识别并加载数据的对象上即可。为了节省空间,建议只为需要动态恢复的对象添加该脚本。
  

  上图使用OGID脚本为对象设置了唯一的ID,Saveable脚本是另一个仅用作保存数据的脚本,它利用[System.Serializable]属性在内部构建数据结构来保存加载对象状态所需的数据,例如位置与方向等。
  存储系统的其它部分就比较简单了,使用内置的路径变量与C#的文件函数,就可以轻松实现管理器。保存和加载数据是整个系统中最简单的部分,创建一些自定义类来存储对象的变换信息及其它数据,添加函数从GameObject读取数据或写入数据到GameObject,然后将脚本绑定到任意需要存档的对象上。此时可以选择使用自定义文件格式存储数据或直接使用[System.Serializable]属性进行标记,然后新建可序列化类包含自定义容器数组,在存储函数中复制数据容器的引用,使用下面的代码将数据保存到文件中:
  System.IO.Stream s = new System.IO.FileStream(filepath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
  System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  formatter.Serialize(s, saveGame);
  s.Close();
  可以选择二进制或XML序列化对数据进行编码。但二者都有自己的长短处:
  二进制:文本文件不易阅读与编辑(对开发者不友好但能够预防玩家作弊),读写速度略快,相比之下数据较易损坏。
  XML:文本文件便于阅读与编辑,读写速度稍慢,文件出错时较易修复。
  本例中采用的是二进制文件,因为它可以将对象保存为二进制字符串,或将二进制字符串还原为对象。
  System.IO.Stream s = new System.IO.FileStream(filepath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
  System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  SaveGame saveGame = (SaveGame) formatter.Deserialize(s);
  s.Close();
  对保存的文件进行反序列化后,可以调用自定义函数将文件中的数据还原为GameObject(通过ID查找)。如果构建文件时遍历带有ID的对象,新对象会被自动保存到文件中。还可以修改代码来保存其它数据类型或调整文件管理器。
  

  使用Unity自带的UGUI可以很方便的实现游戏截图、调整UI布局并创建存档菜单,并从存档中恢复游戏数据。这里存档信息显示了玩家名称与时间戳,以及玩家存档时的游戏截图。
  本文介绍的只是Unity中实现文件存档的其中一点内容,文中的实现方式不一定适用于所有游戏,但其中介绍的思路与关键注意事项可以供大部分游戏参考。
       申请免费学习名额请戳:http://silucg.net/yxdhjc/unity/444.html

回复

使用道具 举报

6蛮牛粉丝
1016/1500
排名
3513
昨日变化
6

1

主题

371

帖子

1016

积分

Rank: 6Rank: 6Rank: 6

UID
122160
好友
1
蛮牛币
1669
威望
0
注册时间
2015-9-10
在线时间
236 小时
最后登录
2018-8-1
发表于 2018-1-9 09:31:41 | 显示全部楼层
感谢分享

回复

使用道具 举报

7日久生情
2710/5000
排名
648
昨日变化
2

30

主题

576

帖子

2710

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
124569
好友
25
蛮牛币
7229
威望
0
注册时间
2015-10-4
在线时间
800 小时
最后登录
2018-12-14
发表于 2018-1-9 11:54:44 | 显示全部楼层
感谢分享
[发帖际遇]: 月半可可 发帖时在路边捡到 1 蛮牛币,偷偷放进了口袋. 幸运榜 / 衰神榜

回复

使用道具 举报

7日久生情
2855/5000
排名
2480
昨日变化
2

2

主题

1848

帖子

2855

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
241666
好友
0
蛮牛币
10740
威望
0
注册时间
2017-9-6
在线时间
443 小时
最后登录
2018-12-9
发表于 2018-1-11 08:00:24 来自Mobile--- | 显示全部楼层
感谢分享好教程

回复

使用道具 举报

7日久生情
4317/5000
排名
2389
昨日变化

5

主题

3108

帖子

4317

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
209186
好友
5
蛮牛币
5515
威望
0
注册时间
2017-3-1
在线时间
631 小时
最后登录
2018-11-8
发表于 2018-1-16 10:47:51 | 显示全部楼层
谢谢分享

回复

使用道具 举报

7日久生情
2088/5000
排名
1840
昨日变化
7

45

主题

773

帖子

2088

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
219600
好友
7
蛮牛币
2895
威望
0
注册时间
2017-4-27
在线时间
568 小时
最后登录
2018-12-14
发表于 2018-1-19 09:57:53 | 显示全部楼层
感谢分享

回复

使用道具 举报

6蛮牛粉丝
1224/1500
排名
2458
昨日变化
10

0

主题

305

帖子

1224

积分

Rank: 6Rank: 6Rank: 6

UID
119648
好友
3
蛮牛币
1730
威望
0
注册时间
2015-8-25
在线时间
357 小时
最后登录
2018-12-14
QQ
发表于 2018-3-7 15:31:10 | 显示全部楼层
感谢分享

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表