如何在没有在线数据库的情况下存储游戏数据

时间:2014-12-17 23:04:48

标签: database database-design unity3d

我正在制作一款旨在脱机播放的游戏。过去我做过需要在线连接的游戏。我们将所有相关数据在线存储在数据库中,我将获取数据库数据,通过JSON将数据解析为对象,并根据需要访问它们。

对于我的离线环境,我不确定如何最好地复制存储所有类型的游戏数据。我真的更喜欢数据库的组织,我不想创建一大堆游戏文件和变量来管理一切。我更喜欢模仿拥有一个数据库,只有它与游戏一起编译。

我考虑使用excel文件,但我觉得这很容易入侵。

您对如何模仿离线数据库有什么建议吗?

我的特定引擎是Unity3D,我使用的是C#。

由于

3 个答案:

答案 0 :(得分:4)

您可以使用本地数据库技术,它们就像您使用在线数据库一样使用,但数据存储在本地计算机上存储的文件中。如果你想在.NET中想到两个:

SQLite - http://www.sqlite.org/

这是defaco本地数据库技术,其开源并且使用非常广泛。甚至还有一个图书馆可以统一它:https://github.com/Busta117/SQLiteUnityKit

SQL CE

这是Micrsofts单文件数据库。它非常类似于SQL Server的功能,它不是开源的,但它已经在.NET框架中内置了驱动程序,因此它可能更易于使用。问题可能在于您希望您的游戏跨平台运行,请看这里: http://answers.unity3d.com/questions/26118/can-you-use-sql-compact-35-with-unity.html

我建议使用SQLite,因为它似乎在Unity中有更多的支持

答案 1 :(得分:1)

Unity可以PlayerPrefs的形式为您完成此操作。根据Unity文档,它:

  

在游戏会话之间存储和访问玩家偏好。

但是,它可以并且经常用于存储诸如高分,教程信息和各种其他离线数据之类的内容。

简单示例:

// this gets the value with the key "score"
// defaults to 0 if it doesn't exist
PlayerPrefs.GetInt("score"); 

// this sets the value with the key "score"
// previous values will be overritten
PlayerPrefs.SetInt("score", 9001);

请注意,这些值不会自动以任何形式加密,但您可以按如下方式包装该函数:

public static int GetIntData(string key, int value)
{
    if(PlayerPrefs.HasKey(key))
    {
        return YourDecryptionMethod(PlayerPrefs.GetInt(key));
    }
    else
    {
        return 0;
    }
}

public static void SetIntData(string key, int value)
{
    return PlayerPrefs.GetInt(key, YourEncryptionMethod(value));
}

如果您愿意,可以更进一步加密密钥。但是对于非常大的数据集,您应该考虑使用数据库(see this answer)

其他

如果您希望将数据存储为JSON,XML或其他格式,那么使用相同的加密/解密包装解决方案,无法阻止您使用可用于流行数据格式的众多解析器之一。

例如,如果您使用的是C#并希望将数据存储为XML,则可以使用System.Xml

如果您选择不使用Mono / .NET类,请查看here有关在项目中使用外部DLL的信息。

答案 2 :(得分:1)

避免将PlayerPrefs用于游戏状态,因为您担心容易被黑客攻击。 PlayerPrefs以纯文本格式存储,它们实际上只应用于存储与配置相关的值。

如果您正在寻找一种本地方式来处理它(即不是SQLite),您可以定期使用.NET文件IO。只需将数据结构放在可序列化的POCO对象模型中即可。保存时,您可以使用以下内容:

BinaryFormatter bin = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/savegame.dat", FileMode.Open);
bf.Serialize(file, mySerializablePoco);
file.Close();

这会将二进制文件写入磁盘,可以在加载过程中反序列化。如果您愿意,也可以添加加密。

如果您不关心修改数据,但只想要设置预定义对象的结构,则可以使用ScriptableObject。我做了一个我们不想使用SQLite的项目,所以我们做了类似的事情:

public class MyRepository : ScriptableObject {
  public List<Car> Cars;
  public List<Driver> Drivers; 
}

[Serializable]
public class Car {
  public string Manufacturer;
}

... ect

在编辑期间创建和设计ScriptableObject。实际上你用一些编辑器代码创建它,它会在你的项目中写出一个* .asset文件。此时,您可以在运行时将Resource.Load挂起或将其连接到MonoBehavior脚本上的公共变量。

退房:http://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects