您如何保存游戏状态?


27

游戏程序员用于保存和恢复游戏状态的程序是什么?像文件/映射。我想将其保存为塔防游戏,并且正在使用unity3D游戏引擎。

Answers:


16

我通常不考虑内存快照,而是仅列出需要在会话之间保存的值并将这些值保存到外部文件中的列表。

当然,这取决于您特定游戏的需求,但是通常我只保存当前关卡的状态(即所有敌人所在的位置,他们的健康状况等),然后存储更高级别的东西(例如玩家的关卡)已经完成了。


3
+1这就是我的方法。我将所需的内容写入二进制文件。而且,如果需要添加一些新内容,请将其添加到末尾,这样就不会破坏旧的保存文件。
chaosTechnician 2011年

这是关于不破坏旧保存文件的一个很好的技巧,尽管最后添加数据与我保存数据的方式无关。我通过对Dictionary进行序列化/反序列化来实现,而顺序在该数据结构中无关紧要。
飞速

(基本上,是
乔纳斯

10

这个答案是Unity3d特有的
在Unity中,大多数类都是可序列化的,这意味着您可以将完整的Unity对象流式传输到磁盘。以下的UnityScript代码是一种序列化对象,将其保存到磁盘上并再次加载的方法(加载后,您必须转换对象):

import System;
import System.IO;
import System.IO.Stream;
import System.Runtime.Serialization;
import System.Runtime.Serialization.Formatters.Binary;

class SaveLoad {
        public static function SaveFile(filename:String, obj:Object):void {
                try {
                        Debug.Log("Writing Stream to Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Create);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        formatter.Serialize(fileStream, obj);
                        fileStream.Close();
                } catch(e:Exception) {
                        Debug.LogWarning("Save.SaveFile(): Failed to serialize object to a file " + filename + " (Reason: " + e.ToString() + ")");
                }
        }

        public static function LoadFile(filename:String):Object {
                try {
                        Debug.Log("Reading Stream from Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Open, FileAccess.Read);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        var obj:Object= formatter.Deserialize(fileStream);
                        fileStream.Close();
                        return obj;
                } catch(e:Exception) {
                        Debug.LogWarning("SaveLoad.LoadFile(): Failed to deserialize a file " + filename + " (Reason: " + e.ToString() + ")");
                        return null;
                }       
        }
}

2
除了使用C#外,您还希望使用PlayerPrefs。它们是跨平台的,您不能在Web / iOS / Android上进行IO。unity3d.com/support/documentation/ScriptReference/…(虽然是不错的示例!)
TJHeuvel 2012年

PlayerPrefs不太灵活,它们确实是跨平台的,并且非常适合存储单个或不相关的值。但是在Windows上,PlayerPrefs以明文形式存储在注册表中。
jonas 2012年

7
如果已经在进行序列化,为什么不将其序列化为String并将其存储在PlayerPrefs中。当然,它的灵活性较差,但它几乎是跨平台游戏的唯一解决方案。
TJHeuvel 2012年

2
PlayerPrefs是伟大的保存像是设置较小的数据,但对于整个游戏你,你应该使用Application.persistentDataPath docs.unity3d.com/ScriptReference/...
jhocking

2
@TJHeuvel:“你不能这样做IO上的Web /的iOS / Android的”你最肯定可以在移动设备上做的IO
普热Wrzesiński

2

对于TD,我可能只在波浪之间保存。这样,您只需考虑的就是塔楼。在关卡中放置一些自动保存点,间隔不超过10分钟,但是最好少一些。

当然,如果您的水平足够短,则只能保存广告系列状态而已,什么也不能保存。


1

当我指游戏的当前状态时,指的是保存时的内存快照。您需要能够从要存储在HDD上的数据中重新创建该数据。

最简单的方法是对所有需要持久化数据的类进行序列化并将其转储到HDD,本质上执行内存转储。问题在于,更改类将更改序列化值的数量/类型并破坏旧的保存。另外,由于您保存了所有内容,因此会增加加载时间。使用序列化器/ IDE使用的任何属性系统,标记有效重建当前“内存快照”所需的各个字段的效率更高。然后从保存的数据重建“内存快照”。

另外,我之前从未使用过Unity,因此可能内置了一些东西。但是,这是典型的方法。


你的意思是我必须将状态存储在文件中吗?
Syed

1
@Syed是的,由于应用程序状态不会保存在内存中,因此最终必须将其写入某种文件。如果要避免整个文件读取/写入内容,可以特别使用Unity使用PlayerPrefs类(我认为它实际上将内容存储在Windows上的注册表中)。
四分
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.