在设备上 运行 时出错,而不是在 Unity 编辑器中
Error when running on device, not in Unity editor
我正在尝试通过 Xcode 将我的游戏的新版本上传到我的 iPhone。使用此应用程序之前这不是问题,但现在我确实遇到了问题。
所以我创建了一个新的较小的项目来测试。它在编辑器中有效,但在上传到我的 iPhone (IOS) 时无效。
我是运行Unity 2021.2.7f1 Apple Silicon。
问题与某些缺少的模块有关,因此我无法从 IOS 打开数据库。
我认为它看起来像是打开数据库的东西,但我不确定。确保数据库复制到“Application.persistentDataPath”路径。
我是运行Unity 2021.2.7f1 Apple Silicon。
"dbconn.Open();"是它在 IOS 而不是 Mac 上失败的地方。我还没有在 Android.
上测试过
这是我的测试项目中的完整代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using Mono.Data.Sqlite;
using System.Data;
using System.IO;
using System;
public class TestScript : MonoBehaviour
{
public TMP_Text txt_Output;
private string dbPath;
private string myRecord;
private static string fileName;
private static IDbConnection dbconn;
private static string connection, checkDbPath;
private static IDbCommand dbcmd;
private static string sqlQuery;
private static IDataReader reader;
private int recCounter;
void Start()
{
//dbPath = Application.dataPath + "/StreamingAssets/TestDB.db";
dbPath = InitDBLocation();
txt_Output.text = "NU STARTAR VI!";
DoTheDB();
}
void DoTheDB()
{
connection = "URI=file:" + dbPath; //Path to database.
dbconn = (IDbConnection)new SqliteConnection(connection); //creates database connection
dbconn.Open();
//sqlQuery = "SELECT MyTable, Name, answer2, answer3, answer4, lvl from questions WHERE id = '" + _idNr.ToString() + "'";
sqlQuery = "SELECT Name FROM MyTable;";
dbcmd = dbconn.CreateCommand();
dbcmd.CommandText = sqlQuery;
reader = dbcmd.ExecuteReader();
while (reader.Read())
{
myRecord = reader.GetString(0);
recCounter++;
}
reader.Close();
dbconn.Close();
reader = null;
dbcmd.Dispose();
dbcmd = null;
dbconn = null;
txt_Output.text = "# RECORDS: " + recCounter.ToString();
}
public static string InitDBLocation()
{
fileName = "TestDB.db";
#if UNITY_EDITOR
Debug.Log("\n #if UNITY_EDITOR \n");
return Application.dataPath + "/StreamingAssets/TestDB.db";
#elif UNITY_ANDROID
Debug.Log("\n #elif UNITY_ANDROID \n");
Debug.Log("========= GET ANDROID PATH =========");
PlayerPrefs.SetString("DB ERROR", "");
oldCurrentDbPathVersion = PlayerPrefs.GetInt("currentDbPathVersion");
Debug.Log("oldCurrentDbPathVersion: " + oldCurrentDbPathVersion + " | currentDbPathVersion: " + currentDbPathVersion);
if (File.Exists(Path.Combine(Application.persistentDataPath, fileName)) && oldCurrentDbPathVersion == currentDbPathVersion)
{
Debug.Log("return Path: " + Path.Combine(Application.persistentDataPath, fileName));
return Path.Combine(Application.persistentDataPath, fileName);
}
else
{
Debug.Log("Copy Database");
if (File.Exists(Path.Combine(Application.persistentDataPath, fileName)))
{
File.Delete(Path.Combine(Application.persistentDataPath, fileName));
}
PlayerPrefs.SetInt("currentDbPathVersion", currentDbPathVersion);
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° //
try
{
var loadingRequest = UnityWebRequest.Get(Path.Combine(Application.streamingAssetsPath, fileName));
loadingRequest.SendWebRequest();
while (!loadingRequest.isDone)
{
if (loadingRequest.isNetworkError || loadingRequest.isHttpError)
{
break;
}
}
Debug.Log("Write database to persistent");
File.WriteAllBytes(Path.Combine(Application.persistentDataPath, fileName), loadingRequest.downloadHandler.data);
Debug.Log("return Path: " + Path.Combine(Application.persistentDataPath, fileName));
return Path.Combine(Application.persistentDataPath, fileName);
}
catch (Exception e)
{
PlayerPrefs.SetString("DB ERROR", e.ToString());
PlayerPrefs.SetString("dbPath", "");
Debug.LogError("*** FILECOPY ERROR ***\n\n" + e); //" + exception.Message + "\n" + exception.StackTrace);
return null;
}
Debug.Log("========= END ANDROID dbPath=========");
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° //
}
#elif UNITY_IOS
Debug.Log("\n #elif UNITY_IOS \n");
Debug.Log("TEST GENERAL: " + Application.streamingAssetsPath);
// ========= IOS ========= //
Debug.Log("========= IOS DB PATH =========");
if (File.Exists(Path.Combine(Application.persistentDataPath, fileName)))
{
Debug.Log("\n>>>> DB File.Exists <<<<<<\n");
return Path.Combine(Application.persistentDataPath, fileName);
}
else
{
if (File.Exists(Path.Combine(Application.persistentDataPath, fileName)))
{
File.Delete(Path.Combine(Application.persistentDataPath, fileName));
}
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° //
try
{
System.IO.File.Copy((Path.Combine(UnityEngine.Application.streamingAssetsPath, fileName)), Path.Combine(Application.persistentDataPath, fileName), true);
Debug.Log("\n return Path: " + Path.Combine(Application.persistentDataPath, fileName));
Debug.Log("\n To PATH: " + Application.persistentDataPath + "\" + fileName);
return Path.Combine(Application.persistentDataPath, fileName);
}
catch (Exception e)
{
Debug.LogError("*** FILECOPY ERROR ***\n\n" + e); //" + exception.Message + "\n" + exception.StackTrace);
PlayerPrefs.SetString("DB ERROR", e.ToString());
PlayerPrefs.SetString("dbPath", "");
return null;
}
Debug.Log("========= END IOS dbPath=========");
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° //
}
#endif
}
}
这是 Xcode 日志:
2022-01-08 22:41:04.039955+0100 NewSQLitetest[2350:900169] Built from '2021.2/staging' branch, Version '2021.2.7f1 (6bd9e232123f)', Build type 'Release', Scripting Backend 'il2cpp'
2022-01-08 22:41:04.040632+0100 NewSQLitetest[2350:900169] MemoryManager: Using 'Default' Allocator.
[UnityMemory] Configuration Parameters - Can be set up in boot.config
"memorysetup-bucket-allocator-granularity=16"
"memorysetup-bucket-allocator-bucket-count=8"
"memorysetup-bucket-allocator-block-size=4194304"
"memorysetup-bucket-allocator-block-count=1"
"memorysetup-main-allocator-block-size=16777216"
"memorysetup-thread-allocator-block-size=16777216"
"memorysetup-gfx-main-allocator-block-size=16777216"
"memorysetup-gfx-thread-allocator-block-size=16777216"
"memorysetup-cache-allocator-block-size=4194304"
"memorysetup-typetree-allocator-block-size=2097152"
"memorysetup-profiler-bucket-allocator-granularity=16"
"memorysetup-profiler-bucket-allocator-bucket-count=8"
"memorysetup-profiler-bucket-allocator-block-size=4194304"
"memorysetup-profiler-bucket-allocator-block-count=1"
"memorysetup-profiler-allocator-block-size=16777216"
"memorysetup-profiler-editor-allocator-block-size=1048576"
"memorysetup-temp-allocator-size-main=4194304"
"memorysetup-job-temp-allocator-block-size=2097152"
"memorysetup-job-temp-allocator-block-size-background=1048576"
"memorysetup-job-temp-allocator-reduction-small-platforms=262144"
"memorysetup-temp-allocator-size-background-worker=32768"
"memorysetup-temp-allocator-size-job-worker=262144"
"memorysetup-temp-allocator-size-preload-manager=262144"
"memorysetup-temp-allocator-size-nav-mesh-worker=65536"
"memorysetup-temp-allocator-size-audio-worker=65536"
"memorysetup-temp-allocator-size-cloud-worker=32768"
"memorysetup-temp-allocator-size-gfx=262144"
-> applicationDidFinishLaunching()
-> applicationDidBecomeActive()
GfxDevice: creating device client; threaded=1; jobified=1
Initializing Metal device caps: Apple A13 GPU
Initialize engine version: 2021.2.7f1 (6bd9e232123f)
2022-01-08 22:41:04.410523+0100 NewSQLitetest[2350:900465] fopen failed for data file: errno = 2 (No such file or directory)
2022-01-08 22:41:04.410600+0100 NewSQLitetest[2350:900465] Errors found! Invalidating cache...
2022-01-08 22:41:04.831038+0100 NewSQLitetest[2350:900465] fopen failed for data file: errno = 2 (No such file or directory)
2022-01-08 22:41:04.831115+0100 NewSQLitetest[2350:900465] Errors found! Invalidating cache...
2022-01-08 22:41:05.052099+0100 NewSQLitetest[2350:900169] Unbalanced calls to begin/end appearance transitions for <UnityDefaultViewController: 0x103429f00>.
UnloadTime: 1.043667 ms
#elif UNITY_IOS
TestScript:InitDBLocation()
TestScript:Start()
TEST GENERAL: /private/var/containers/Bundle/Application/2FE4741C-1580-4698-9BC1-9512D578CFF6/NewSQLitetest.app/Data/Raw
TestScript:InitDBLocation()
TestScript:Start()
========= IOS DB PATH =========
TestScript:InitDBLocation()
TestScript:Start()
return Path: /var/mobile/Containers/Data/Application/F3747560-C7AD-4FBC-A1C6-F95843F09906/Documents/TestDB.db
TestScript:InitDBLocation()
TestScript:Start()
To PATH: /var/mobile/Containers/Data/Application/F3747560-C7AD-4FBC-A1C6-F95843F09906/DocumentsTestDB.db
TestScript:InitDBLocation()
TestScript:Start()
MissingMethodException: System.Runtime.InteropServices.Marshal::SetLastWin32Error(System.Int32)
at System.Runtime.InteropServices.CriticalHandle.Cleanup () [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.Sqlite.SqliteStatement.Dispose () [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.Sqlite.SqliteCommand.ClearCommands () [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.Sqlite.SqliteCommand.set_CommandText (System.String value) [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.Sqlite.SqliteConnection.Open () [0x00000] in <00000000000000000000000000000000>:0
at TestScript.DoTheDB () [0x00000] in <00000000000000000000000000000000>:0
我终于根据上面的post解决了这个问题,见我评论中的线程。来自 Baydogan 的评论:
我终于找到了解决方法,直到 unity 修复了这个错误。
- 不要修改任何统一编辑器文件。像往常一样为 iOS 构建。
- 在 xcode 项目中搜索“// System.Void System.Runtime.InteropServices.CriticalHandle::Cleanup()”。
- 在下面移动几行并注释掉开头的行:“Marshal_SetLastWin32Error_”
- 完成
示例:
IL_002b:
{ il2cpp_codegen_runtime_class_init_inline(Marshal_tD976A56A90263C3CE2B780D4B1CADADE2E70B4A7_il2cpp_TypeInfo_var);
// Marshal_SetLastWin32Error_mC871D8DAC36418FAA95AFD23CD2A3ECC94628D1C(G_B6_0, NULL); il2cpp_codegen_runtime_class_init_inline(GC_t920F9CF6EBB7C787E5010A4352E1B587F356DC58_il2cpp_TypeInfo_var);
GC_SuppressFinalize_m3352E2F2119EB46913B51B7AAE2F217C63C35F2A(__this, NULL);
return;
}
我正在尝试通过 Xcode 将我的游戏的新版本上传到我的 iPhone。使用此应用程序之前这不是问题,但现在我确实遇到了问题。
所以我创建了一个新的较小的项目来测试。它在编辑器中有效,但在上传到我的 iPhone (IOS) 时无效。
我是运行Unity 2021.2.7f1 Apple Silicon。
问题与某些缺少的模块有关,因此我无法从 IOS 打开数据库。
我认为它看起来像是打开数据库的东西,但我不确定。确保数据库复制到“Application.persistentDataPath”路径。
我是运行Unity 2021.2.7f1 Apple Silicon。
"dbconn.Open();"是它在 IOS 而不是 Mac 上失败的地方。我还没有在 Android.
上测试过这是我的测试项目中的完整代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using Mono.Data.Sqlite;
using System.Data;
using System.IO;
using System;
public class TestScript : MonoBehaviour
{
public TMP_Text txt_Output;
private string dbPath;
private string myRecord;
private static string fileName;
private static IDbConnection dbconn;
private static string connection, checkDbPath;
private static IDbCommand dbcmd;
private static string sqlQuery;
private static IDataReader reader;
private int recCounter;
void Start()
{
//dbPath = Application.dataPath + "/StreamingAssets/TestDB.db";
dbPath = InitDBLocation();
txt_Output.text = "NU STARTAR VI!";
DoTheDB();
}
void DoTheDB()
{
connection = "URI=file:" + dbPath; //Path to database.
dbconn = (IDbConnection)new SqliteConnection(connection); //creates database connection
dbconn.Open();
//sqlQuery = "SELECT MyTable, Name, answer2, answer3, answer4, lvl from questions WHERE id = '" + _idNr.ToString() + "'";
sqlQuery = "SELECT Name FROM MyTable;";
dbcmd = dbconn.CreateCommand();
dbcmd.CommandText = sqlQuery;
reader = dbcmd.ExecuteReader();
while (reader.Read())
{
myRecord = reader.GetString(0);
recCounter++;
}
reader.Close();
dbconn.Close();
reader = null;
dbcmd.Dispose();
dbcmd = null;
dbconn = null;
txt_Output.text = "# RECORDS: " + recCounter.ToString();
}
public static string InitDBLocation()
{
fileName = "TestDB.db";
#if UNITY_EDITOR
Debug.Log("\n #if UNITY_EDITOR \n");
return Application.dataPath + "/StreamingAssets/TestDB.db";
#elif UNITY_ANDROID
Debug.Log("\n #elif UNITY_ANDROID \n");
Debug.Log("========= GET ANDROID PATH =========");
PlayerPrefs.SetString("DB ERROR", "");
oldCurrentDbPathVersion = PlayerPrefs.GetInt("currentDbPathVersion");
Debug.Log("oldCurrentDbPathVersion: " + oldCurrentDbPathVersion + " | currentDbPathVersion: " + currentDbPathVersion);
if (File.Exists(Path.Combine(Application.persistentDataPath, fileName)) && oldCurrentDbPathVersion == currentDbPathVersion)
{
Debug.Log("return Path: " + Path.Combine(Application.persistentDataPath, fileName));
return Path.Combine(Application.persistentDataPath, fileName);
}
else
{
Debug.Log("Copy Database");
if (File.Exists(Path.Combine(Application.persistentDataPath, fileName)))
{
File.Delete(Path.Combine(Application.persistentDataPath, fileName));
}
PlayerPrefs.SetInt("currentDbPathVersion", currentDbPathVersion);
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° //
try
{
var loadingRequest = UnityWebRequest.Get(Path.Combine(Application.streamingAssetsPath, fileName));
loadingRequest.SendWebRequest();
while (!loadingRequest.isDone)
{
if (loadingRequest.isNetworkError || loadingRequest.isHttpError)
{
break;
}
}
Debug.Log("Write database to persistent");
File.WriteAllBytes(Path.Combine(Application.persistentDataPath, fileName), loadingRequest.downloadHandler.data);
Debug.Log("return Path: " + Path.Combine(Application.persistentDataPath, fileName));
return Path.Combine(Application.persistentDataPath, fileName);
}
catch (Exception e)
{
PlayerPrefs.SetString("DB ERROR", e.ToString());
PlayerPrefs.SetString("dbPath", "");
Debug.LogError("*** FILECOPY ERROR ***\n\n" + e); //" + exception.Message + "\n" + exception.StackTrace);
return null;
}
Debug.Log("========= END ANDROID dbPath=========");
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° //
}
#elif UNITY_IOS
Debug.Log("\n #elif UNITY_IOS \n");
Debug.Log("TEST GENERAL: " + Application.streamingAssetsPath);
// ========= IOS ========= //
Debug.Log("========= IOS DB PATH =========");
if (File.Exists(Path.Combine(Application.persistentDataPath, fileName)))
{
Debug.Log("\n>>>> DB File.Exists <<<<<<\n");
return Path.Combine(Application.persistentDataPath, fileName);
}
else
{
if (File.Exists(Path.Combine(Application.persistentDataPath, fileName)))
{
File.Delete(Path.Combine(Application.persistentDataPath, fileName));
}
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° //
try
{
System.IO.File.Copy((Path.Combine(UnityEngine.Application.streamingAssetsPath, fileName)), Path.Combine(Application.persistentDataPath, fileName), true);
Debug.Log("\n return Path: " + Path.Combine(Application.persistentDataPath, fileName));
Debug.Log("\n To PATH: " + Application.persistentDataPath + "\" + fileName);
return Path.Combine(Application.persistentDataPath, fileName);
}
catch (Exception e)
{
Debug.LogError("*** FILECOPY ERROR ***\n\n" + e); //" + exception.Message + "\n" + exception.StackTrace);
PlayerPrefs.SetString("DB ERROR", e.ToString());
PlayerPrefs.SetString("dbPath", "");
return null;
}
Debug.Log("========= END IOS dbPath=========");
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° //
}
#endif
}
}
这是 Xcode 日志:
2022-01-08 22:41:04.039955+0100 NewSQLitetest[2350:900169] Built from '2021.2/staging' branch, Version '2021.2.7f1 (6bd9e232123f)', Build type 'Release', Scripting Backend 'il2cpp'
2022-01-08 22:41:04.040632+0100 NewSQLitetest[2350:900169] MemoryManager: Using 'Default' Allocator.
[UnityMemory] Configuration Parameters - Can be set up in boot.config
"memorysetup-bucket-allocator-granularity=16"
"memorysetup-bucket-allocator-bucket-count=8"
"memorysetup-bucket-allocator-block-size=4194304"
"memorysetup-bucket-allocator-block-count=1"
"memorysetup-main-allocator-block-size=16777216"
"memorysetup-thread-allocator-block-size=16777216"
"memorysetup-gfx-main-allocator-block-size=16777216"
"memorysetup-gfx-thread-allocator-block-size=16777216"
"memorysetup-cache-allocator-block-size=4194304"
"memorysetup-typetree-allocator-block-size=2097152"
"memorysetup-profiler-bucket-allocator-granularity=16"
"memorysetup-profiler-bucket-allocator-bucket-count=8"
"memorysetup-profiler-bucket-allocator-block-size=4194304"
"memorysetup-profiler-bucket-allocator-block-count=1"
"memorysetup-profiler-allocator-block-size=16777216"
"memorysetup-profiler-editor-allocator-block-size=1048576"
"memorysetup-temp-allocator-size-main=4194304"
"memorysetup-job-temp-allocator-block-size=2097152"
"memorysetup-job-temp-allocator-block-size-background=1048576"
"memorysetup-job-temp-allocator-reduction-small-platforms=262144"
"memorysetup-temp-allocator-size-background-worker=32768"
"memorysetup-temp-allocator-size-job-worker=262144"
"memorysetup-temp-allocator-size-preload-manager=262144"
"memorysetup-temp-allocator-size-nav-mesh-worker=65536"
"memorysetup-temp-allocator-size-audio-worker=65536"
"memorysetup-temp-allocator-size-cloud-worker=32768"
"memorysetup-temp-allocator-size-gfx=262144"
-> applicationDidFinishLaunching()
-> applicationDidBecomeActive()
GfxDevice: creating device client; threaded=1; jobified=1
Initializing Metal device caps: Apple A13 GPU
Initialize engine version: 2021.2.7f1 (6bd9e232123f)
2022-01-08 22:41:04.410523+0100 NewSQLitetest[2350:900465] fopen failed for data file: errno = 2 (No such file or directory)
2022-01-08 22:41:04.410600+0100 NewSQLitetest[2350:900465] Errors found! Invalidating cache...
2022-01-08 22:41:04.831038+0100 NewSQLitetest[2350:900465] fopen failed for data file: errno = 2 (No such file or directory)
2022-01-08 22:41:04.831115+0100 NewSQLitetest[2350:900465] Errors found! Invalidating cache...
2022-01-08 22:41:05.052099+0100 NewSQLitetest[2350:900169] Unbalanced calls to begin/end appearance transitions for <UnityDefaultViewController: 0x103429f00>.
UnloadTime: 1.043667 ms
#elif UNITY_IOS
TestScript:InitDBLocation()
TestScript:Start()
TEST GENERAL: /private/var/containers/Bundle/Application/2FE4741C-1580-4698-9BC1-9512D578CFF6/NewSQLitetest.app/Data/Raw
TestScript:InitDBLocation()
TestScript:Start()
========= IOS DB PATH =========
TestScript:InitDBLocation()
TestScript:Start()
return Path: /var/mobile/Containers/Data/Application/F3747560-C7AD-4FBC-A1C6-F95843F09906/Documents/TestDB.db
TestScript:InitDBLocation()
TestScript:Start()
To PATH: /var/mobile/Containers/Data/Application/F3747560-C7AD-4FBC-A1C6-F95843F09906/DocumentsTestDB.db
TestScript:InitDBLocation()
TestScript:Start()
MissingMethodException: System.Runtime.InteropServices.Marshal::SetLastWin32Error(System.Int32)
at System.Runtime.InteropServices.CriticalHandle.Cleanup () [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.Sqlite.SqliteStatement.Dispose () [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.Sqlite.SqliteCommand.ClearCommands () [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.Sqlite.SqliteCommand.set_CommandText (System.String value) [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.Sqlite.SqliteConnection.Open () [0x00000] in <00000000000000000000000000000000>:0
at TestScript.DoTheDB () [0x00000] in <00000000000000000000000000000000>:0
我终于根据上面的post解决了这个问题,见我评论中的线程。来自 Baydogan 的评论:
我终于找到了解决方法,直到 unity 修复了这个错误。
- 不要修改任何统一编辑器文件。像往常一样为 iOS 构建。
- 在 xcode 项目中搜索“// System.Void System.Runtime.InteropServices.CriticalHandle::Cleanup()”。
- 在下面移动几行并注释掉开头的行:“Marshal_SetLastWin32Error_”
- 完成
示例:
IL_002b:
{ il2cpp_codegen_runtime_class_init_inline(Marshal_tD976A56A90263C3CE2B780D4B1CADADE2E70B4A7_il2cpp_TypeInfo_var);
// Marshal_SetLastWin32Error_mC871D8DAC36418FAA95AFD23CD2A3ECC94628D1C(G_B6_0, NULL); il2cpp_codegen_runtime_class_init_inline(GC_t920F9CF6EBB7C787E5010A4352E1B587F356DC58_il2cpp_TypeInfo_var);
GC_SuppressFinalize_m3352E2F2119EB46913B51B7AAE2F217C63C35F2A(__this, NULL);
return;
}