目录
特别说明
- Unity 3D可以通过自建Plugins文件夹,放入SQLite相关配置文件,引入命名空间的方式快速实现对数据库的访问。具体步骤见此文:【极简代码】Unity C#连接查询SQLite数据库并支持安卓系统
- 但是,Godot与Unity 3D很大不同,无法直接解析导入项目中的dll文件。网络上普遍的解决方案就是借助Visual Studio强大的Nuget功能,引入Microsoft.Data.Sqlite包(System.Data.SQLite包、SQLite包和Mono.Data.Sqlite.Portable包等都没有Microsoft.Data.Sqlite包好用,更何况System.Data.SQLite包中另有2000美刀的收费模块)。笔者经过多番尝试后发现,Nuget包只适用于PC平台,即打包出exe文件后读写SQLite数据库均无问题,而一旦打包成apk文件,在安卓真机上运行时,就会报“DllNotFoundException:e_sqlite3”这样的错误,即使把Sqlite3.dll文件拷贝到项目目录也不行,VS也无法像引入程序集一样引入这个Sqlite3.dll文件。
- 综上所述,如果只想实现PC端读写Sqlite数据库,最省事的办法就是通过Nuget引入Microsoft.Data.Sqlite包。如果想实现PC和安卓多端兼容,就得使用一个“曲线救国”的办法——借助Godot SQLite插件。
环境配置
主要是对Godot做一些配置,包括插件的安装与启用、SQLite文件的“非资源文件筛选”、外部文件读写权限的开启、Godot面向安卓端的路径寻址等:
- 在Godot AssetLib资源商店搜搜并安装Godot-SQLite插件,然后在Gddot菜单栏“项目—项目设置—插件”中启动该插件;
- 在Godot安卓导出界面“资源—筛选导出非资源文件或文件夹”中填写SQLite文件,如res://SqliteTest.db,*.db;
- 在Godot安卓导出界面勾选启用“ReadExternalStorage”和“WriteExternalStorage”;
- Godot提供的“res://”和“user://”这两个地址各有一个坑:“res://”中的文件具备只读(ReadOnly)功能,对只读类型的数据库比较适用,但必须在GDScript脚本中明确添加一句代码
db.read_only=true
才算是真正开启了对该数据库的访问;“user://”所对应的安卓端地址是“/data/data/com.example.$genname/files”,该文件夹在非root手机中是看不到的,所以很不好通过外部管理数据库文件,而在非root手机中能够看到的文件夹是“/Storage/Emulated/0/Android/data/com.example.genname/files”,该文件夹在Godot中对应的访问方式是OS.GetSystemDir(OS.SystemDir.Desktop, false)
,在Unity 3D中对应的访问方式是Application.PersistentDataPath
; - 通过C#与GDScript通信功能,实现C#对Godot-SQLite插件的间接调用:
GDScript myGDScript = GD.Load<GDScript>("res://scripts/CanvasLayerSqlite.gd");//1.脚本寻址 sqliteObj = (GodotObject)myGDScript.New();//2.实例化脚本 labelMsg.Text = sqliteObj.Get("dbpath").ToString();//3.获取GD脚本中的字段 Variant result = sqliteObj.Call("db_insert", sql);//4.传参调用脚本中的函数
; - 为什么要用C#与GDScript通信来调用Godot-SQLite插件,而不直接使用GDScript?答:探索出一条新路,供Godot Mono用户群参考。
C#代码片
using Godot;
using Godot.Collections;
using System;
using System.IO;
public partial class SQLiteManager : CanvasLayer
{
GodotObject sqliteObj;
Button butttonLogin, butttonLogup, buttonQuit;
LineEdit lineEditUser, lineEditPwd;
Label labelMsg;
bool isUserExisted = false;
//change bgimg
int imgIndex = 0;
FileInfo[] fileInfos;
public override void _Ready()
{
GDScript myGDScript = GD.Load<GDScript>("res://scripts/CanvasLayerSqlite.gd");
sqliteObj = (GodotObject)myGDScript.New();
InitComps();
//labelMsg.Text = OS.GetSystemDir(OS.SystemDir.Desktop, false);
//labelMsg.Text = "数据库所有数据:" + sqliteObj.Call("db_sel_all").ToString();
//sqliteObj.Call("my_ready");
try
{
butttonLogin.Pressed += CheckLogin;
butttonLogup.