LiteDB和Unity

Tulenber 19 June, 2020 ⸱ Intermediate ⸱ 4 min ⸱ 2019.4.0f1 ⸱

让我们看一下LiteDB,它是当前游戏存储标准的noSql替代方案。

在过去的十年中,noSql解决方案逐渐渗透到基本的开发工具集中。这是可以理解的,因为关系数据库所提供的功能不再那么需要,并且迁移到纯noSql所获得的性能永远不会过高。在有关为Unity选择数据存储方法的文章中,我们得出结论,事实上的行业标准是SQLite,它不仅可以适用于关系用例,而且可以以noSql解决方案的形式进行调整。纯粹的noSql解决方案并不那么受欢迎,它们是开源项目中最聪明的示例。但是,如前所述,如果您的灵魂渴望冒险,并且该项目没有声称要占领整个世界,那么为什么不尝试一下。

LiteDB

LiteDB是一个用.NET编写的嵌入式noSql数据库,可轻松在最新Unity版本的项目中使用。这是一个具有较小巴士因子的小型项目,但它具有您需要用作完整的嵌入式数据库的所有内容。数据库不是游戏创建中的大问题,因此没有那么多受欢迎的解决方案,并且LiteDB是SQLite替代方案中最明显的选项。更准确地说,它至少在某种程度上引人注目,并且您至少可以找到有关其应用程序的信息。例如,马克·赫德伯格(Mark Hedberg)的博客文章就是这样的一篇文章,他在其中分享了他的使用经验。第二个来自Andrey Podkolzin,他比较了LiteDb,SQLite和平面文件之间的性能。

文献资料

相当简洁的文档可以在官方网站上找到。

内部组织

有关数据库内部结构的说明,可在文档的相应部分-数据结构中找到

建立

转到nuget.org上的软件包页面,从下载软件包链接下载所需的版本,将下载文件的扩展名重命名为.zip,解压缩并将适用于您的脚本后端的Dll版本复制到该项目。

另外,您还需要使用这些设置创建一个文件link.xml感谢TigerHix的要旨

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<linker>
    <assembly fullname="System">
        <type fullname="System.ComponentModel.TypeConverter" preserve="all"/>
        <type fullname="System.ComponentModel.ArrayConverter" preserve="all"/>
        <type fullname="System.ComponentModel.BaseNumberConverter" preserve="all"/>
        <type fullname="System.ComponentModel.BooleanConverter" preserve="all"/>
        <type fullname="System.ComponentModel.ByteConverter" preserve="all"/>
        <type fullname="System.ComponentModel.CharConverter" preserve="all"/>
        <type fullname="System.ComponentModel.CollectionConverter" preserve="all"/>
        <type fullname="System.ComponentModel.ComponentConverter" preserve="all"/>
        <type fullname="System.ComponentModel.CultureInfoConverter" preserve="all"/>
        <type fullname="System.ComponentModel.DateTimeConverter" preserve="all"/>
        <type fullname="System.ComponentModel.DecimalConverter" preserve="all"/>
        <type fullname="System.ComponentModel.DoubleConverter" preserve="all"/>
        <type fullname="System.ComponentModel.EnumConverter" preserve="all"/>
        <type fullname="System.ComponentModel.ExpandableObjectConverter" preserve="all"/>
        <type fullname="System.ComponentModel.Int16Converter" preserve="all"/>
        <type fullname="System.ComponentModel.Int32Converter" preserve="all"/>
        <type fullname="System.ComponentModel.Int64Converter" preserve="all"/>
        <type fullname="System.ComponentModel.NullableConverter" preserve="all"/>
        <type fullname="System.ComponentModel.SByteConverter" preserve="all"/>
        <type fullname="System.ComponentModel.SingleConverter" preserve="all"/>
        <type fullname="System.ComponentModel.StringConverter" preserve="all"/>
        <type fullname="System.ComponentModel.TimeSpanConverter" preserve="all"/>
        <type fullname="System.ComponentModel.UInt16Converter" preserve="all"/>
        <type fullname="System.ComponentModel.UInt32Converter" preserve="all"/>
        <type fullname="System.ComponentModel.UInt64Converter" preserve="all"/>
    </assembly>
    
    <!--https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.lambdaexpression.name?view=netframework-4.7.2&viewFallbackFrom=netframework-2.0-->
    <assembly fullname="System.Core">
        <type fullname="System.Linq.Expressions" preserve="all"/>
        <type fullname="System.Linq.Expressions.*" preserve="all"/>
        <type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all"/>
        <type fullname="System.Linq.Expressions.LambdaExpression" preserve="all"/>
    </assembly>
    <assembly fullname="System.Linq.Expressions">
        <type fullname="System.Linq.Expressions" preserve="all"/>
        <type fullname="System.Linq.Expressions.*" preserve="all"/>
        <type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all"/>
        <type fullname="System.Linq.Expressions.LambdaExpression" preserve="all"/>
    </assembly>
    <assembly fullname="netstandard">
        <type fullname="System.Linq.Expressions" preserve="all"/>
        <type fullname="System.Linq.Expressions.*" preserve="all"/>
        <type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all"/>
        <type fullname="System.Linq.Expressions.LambdaExpression" preserve="all"/>
    </assembly>
    <assembly fullname="LiteDB" preserve="all"/>
</linker>

用法

由于实际项目的代码不太适合公开演示,因此创建了一个最小的实现来模拟实际应用。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
using System.IO;
using System.Linq;
using LiteDB;
using UnityEngine;
using UnityEngine.UI;

// POCO存储对象
public class GameData
{
    // 需要在数据库中存储对象的ID
    public int Id { get; set; }
    // 点击计数器
    public int Counter { get; set; }
}

// 数据库使用类别
public class DatabaseManager : MonoBehaviour
{
    // 链接到柜台文字
    public Text text = null;

    // 访问数据库的参数
    private string _connectionString;
    private string _databaseName;
    
    // 在第一帧更新之前调用开始
    void Start()
    {
        // 配置访问设置
        _connectionString = "Filename=" + Path.Combine(Application.persistentDataPath, "database");
        _databaseName = "gameData";

        // 显示初始数据
        text.text = GetGameData().Counter.ToString();
    }

    // 点击计数器增加按钮
    public void IncreaseClick()
    {
        // 从数据库获取对象
        GameData gameData = GetGameData();
        // 增量计数器
        gameData.Counter += 1;
        // 将对象保存到数据库
        StoreGameData(gameData);

        // 通过接收对象来更新文本(仅用于测试目的)
        text.text = GetGameData().Counter.ToString();
    }

    // 单击清除数据库按钮
    public void ClearClick()
    {
        // 清除数据库
        ClearData();

        // 更新文字
        text.text = GetGameData().Counter.ToString();
    }

    // 将对象保存到数据库
    private void StoreGameData(GameData gameData)
    {
        // 连接到数据库
        using(var db = new LiteDatabase(_connectionString))
        {
            // 获取集合(如果不存在则创建)
            var col = db.GetCollection<GameData>(_databaseName);

            // 添加或更新对象
            col.Upsert(gameData);
        }
    }

    // 从数据库获取对象
    private GameData GetGameData()
    {
        // 连接到数据库
        using(var db = new LiteDatabase(_connectionString))
        {
            // 获取集合(如果不存在则创建)
            var col = db.GetCollection<GameData>(_databaseName);

            // 如果它不在数据库中,则创建一个新对象
            if (col.Count() == 0)
            {
                GameData gameData = new GameData();
                gameData.Counter = 0;
                return gameData;
            }

            // 从数据库获取对象
            var result = col.FindAll();
            return result.First();
        }
    }

    // 清除数据库
    private void ClearData()
    {
        // 连接到数据库
        using(var db = new LiteDatabase(_connectionString))
        {
            // 获取集合(如果不存在则创建)
            var col = db.GetCollection<GameData>(_databaseName);

            // 清除收藏
            col.DeleteAll();
        }
    }
}

结果

Result

坏处

使用此数据库的主要不利方面是缺少一种工具,可以在Windows以外的平台上查看其内容,但是您可以自己解决它。

结论]

用于在Unity上存储项目信息的标准方法是SQLite。这是一个简单的数据库,可以从中清楚地预期到什么。在没有严重理由的情况下将其更改为时髦的东西没有任何意义。但是,如果您要开始一个新项目,那么很有可能考虑使用LiteDB作为替代方案。在个人项目中使用此数据库的经验并未显示任何负面影响,因此我们可以尝试将其用于更关键的项目,我们将在以后讨论。下次见!^_^


如果您喜欢这篇文章,可以为它提供支持



Privacy policyCookie policyTerms of service
Tulenber 2020