开源地址: huatuo

现在市面上使用比较多的就是xlua等几个lua热更方案,纯c#的热更方案有ilruntime。每个方案都有各自存在的道理,水群里面经常出来一些“干死lua”之类的声音,这事儿在我看duck不必。我不喜欢lua的原因是因为引擎本身就有一层黑盒子 用了lua之后把游戏代码又封了一层。层层加码之后实际上阻碍了团队部分人员能力的提升.
回到正题。项目目前用的是ILRuntime,因为是第一个unity项目,团队成员对unity以及c#的把控能力不高出现了以下一些问题:

  • 频繁的添加适配器
  • 频繁的添加委托
  • AOT裁减

就目前而言huatuo宣称上能够很好的解决以上的部分问题,使用起来简易不少。问题比较大就是对il2cpp的代码入侵较大,在没有成功上线项目下感觉要趟不少坑。跟着官方项目走基本能熟悉流程;我用自己的项目从ILRuntime切到华佗后遇到了以下一些问题:

  • 打包的Mac项目报找不到imageplayersetting里面需要把ios也选上.NET 4.x
  • [Android] * error only support 64bit。顾命思议,playsetting那边勾选arm64,自己的SDK工程中的Gradle也需要进行对应的64位调整
    1
    2
    3
    ndk {
    abiFilters 'arm64-v8a'
    }
  • [裁减] TypeLoadException: Could not load type ‘System.ValueTuple`6’。 需要在主工程中添加对应的ValueTuple,不太友好,看不到ValueTuple对应的参数类型。在一些如果是dll插件的话比较难定位
  • [裁减]Could not load type ‘System.Lazy`1’。同上

参考: unity代码防裁减

截止到现在游戏项目仍然没能在手机上跑起来….附上一些调试步骤

安卓真机crash后会有以下一些信息

1
2
3
4
5
6
7
8
9
10
11
12
E/CRASH: backtrace:
E/CRASH: #00 pc 0000000000aa20ac libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #01 pc 0000000000aa0534 libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #02 pc 0000000000a9f860 libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #03 pc 0000000000a9f74c libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #04 pc 000000000093c354 libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #05 pc 000000000091c7a0 libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #06 pc 0000000001582288 libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #07 pc 00000000011dd77c libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #08 pc 00000000011dcdcc libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #09 pc 00000000007bf4e8 libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)
E/CRASH: #10 pc 000000000093f044 libil2cpp.so (BuildId: 78b0ff9a36c4fbf64f45dd27cb7f4cc5a15cdc9f)

直接就用NDK(引擎安装目录:/Applications/Unity/Hub/Editor/2020.3.7f1c1/PlaybackEngines/AndroidPlayer/NDK/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line)中的工具获取so的符号表定位到对应的行号

参考 bugly符号表上传

unity导出的AndroidStudion工程从gradle中可以看到把带符号表的so生成到了unityLibrary/symbols/arm64-v8a/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def BuildIl2Cpp(String workingDir, String targetDirectory, String architecture, String abi, String configuration) {
exec {
commandLine(workingDir + "/src/main/Il2CppOutputProject/IL2CPP/build/deploy/netcoreapp3.1/il2cpp",
"--compile-cpp",
"--libil2cpp-static",
"--platform=Android",
"--architecture=" + architecture,
"--configuration=" + configuration,
"--outputpath=" + workingDir + targetDirectory + abi + "/libil2cpp.so",
"--cachedirectory=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_cache",
"--additional-include-directories=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/external/bdwgc/include",
"--additional-include-directories=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/libil2cpp/include",
"--tool-chain-path=" + android.ndkDirectory,
"--map-file-parser=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/MapFileParser/MapFileParser.exe",
"--generatedcppdir=" + workingDir + "/src/main/Il2CppOutputProject/Source/il2cppOutput",
"--baselib-directory=" + workingDir + "/src/main/jniStaticLibs/" + abi,
"--dotnetprofile=unityaot")
environment "ANDROID_SDK_ROOT", getSdkDir()
}
delete workingDir + targetDirectory + abi + "/libil2cpp.sym.so"
ant.move(file: workingDir + targetDirectory + abi + "/libil2cpp.dbg.so", tofile: workingDir + "/symbols/" + abi + "/libil2cpp.so")
}

命令行(-f -C -e 这些参数通过 -h看对应的描述;方便后续查问题,把aarch64-linux-android-addr2line加到环境变量里面)

1
aarch64-linux-android-addr2line -f -C -e proj.android/unityLibrary/symbols/arm64-v8a/libil2cpp.so 0000000000aa20ac 0000000000aa0534 0000000000a9f860

结果如下

1
2
3
4
5
6
huatuo::metadata::Image::InitConsts()
proj.android/unityLibrary/src/main/Il2CppOutputProject/IL2CPP/libil2cpp/huatuo/metadata/Image.cpp:366
huatuo::metadata::Image::InitRuntimeMetadatas()
proj.android/unityLibrary/src/main/Il2CppOutputProject/IL2CPP/libil2cpp/huatuo/metadata/Image.cpp:110
huatuo::metadata::Assembly::Create(unsigned char const*, unsigned long, bool)
SDK/proj.android/unityLibrary/src/main/Il2CppOutputProject/IL2CPP/libil2cpp/huatuo/metadata/Assembly.cpp:118

感受

  • 工作流欠缺
    • 类似ILRuntime的CLR绑定

      引用 蓝大 蓝色幻想的话就是:clr自动分析绑定,你值得拥有 这玩意非常一大用处就是防泛型剪裁,是唯一可靠的途径。CLR绑定

    • 泛型友好提示。类似ILRuntime在缺少Delegate时候的提示:
      1
      appdomain.DelegateManager.RegisterFunctionDelegate<UnityEngine.GameObject, System.Boolean>();
  • 还没看到有项目说在用

其他已知问题

  • protobuf-net 不支持v.2.x之后的版本,r668可用
  • json
    库名称 是否可用
    utf8json
    newtonsoftjson
    catjson
    litjson -