利用Unity开发3d模块,将3d模块嵌入Android项目。
Android Studio 2020.3.1 Patch3
Gradle 6.1.1
Android Gradle Plugin(AGP) 3.1.4
Unity 2020.3.20f1c1
当前Android 嵌入Unity模块的方案:
Unity采用Mono编译,导出AndroidProject,在主Android项目中引入AndroidProject中的UnityLibiary。
后来将Unity设置为il2cpp,然后依照上述步骤构建Android项目时候,报错
Execution failed for task ':unityLibrary:compileDebugNdk'.
Error: Your project contains C++ files but it is not using a supported native build system. Consider using CMake or ndk-build integration. For more information, go to: https://d.android.com/r/studio-ui/add-native-code.html Alternatively, you can use the experimental plugin: https://developer.android.com/r/tools/experimental-plugin.html
经过测试,是将Android Gradle Plugin版本调整为 3.4.0 可以构建成功,3.3+版本则编译不通过。
但是由于Android主工程限制Android Gradle Plugin必须为3.1.4。所以不能通过升级Android Gradle Plugin解决问题。
经过分析Unity到出的AS工程中的Gradle文件做出以下分析:
改为il2cpp后,工程内有c++代码,但是Android工程没有配置NDK或者cmake编译,所以AGP3.1.4认为这是不合理的,故报上述错误。分析Unit生成的文件,之所以 Unity 导出的工程没配置NDK 、cmake 编译,是因为 unity是通过自己的il2cpp.exe程序构建的,不需要“Add c++ to Moudle”。
主要是Gradle文件中的BuildIl2Cpp在负责c++的构建过程。
def BuildIl2Cpp(String workingDir, String targetDirectory, String architecture, String abi, String configuration) {
exec {
commandLine(workingDir + "/src/main/Il2CppOutputProject/IL2CPP/build/deploy/netcoreapp3.1/il2cpp.exe",
"--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")
}
android {
task BuildIl2CppTask {
doLast {
BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), '/src/main/jniLibs/', 'ARMv7', 'armeabi-v7a', 'Release');
}
}
afterEvaluate {
if (project(':unityLibrary').tasks.findByName('mergeDebugJniLibFolders'))
project(':unityLibrary').mergeDebugJniLibFolders.dependsOn BuildIl2CppTask
if (project(':unityLibrary').tasks.findByName('mergeReleaseJniLibFolders'))
project(':unityLibrary').mergeReleaseJniLibFolders.dependsOn BuildIl2CppTask
}
sourceSets {
main {
jni.srcDirs = ["src/main/Il2CppOutputProject"]
}
}
}
经测试,先用AGP3.5 构建工程然后,注释掉gradle 文件中 il2cpp.exe的构建过程,同时删除c++代码后,然后改用AGP3.1.4 插件,构建通过,程序正常运行。
过经过分析大致得出以下几个解决方案
升级AGP到3.4以上版本(因为项目限制,本项目不适用)
降级Unity到一个旧版本,找一个和AGP3.1.4同时代的旧版本(只是个方案而已,不推荐)
升级AGP到3.4以上版本,构建好Unity项目中的c++,然后删除c++文件(即src/main/Il2CppOutputProject目录),然后删除Gradleil2cpp构建步骤(即上边贴出的代码),将AGP改回到3.1.4(实验过程得出的方案,很绕,不推荐)
将Unity导出的Android构建成aar,给Android主工程调用(AGP用Unity默认的版本4.0.1即可)。(本项目最适用的方案)
问题根源Android项目太老,Unity项目较新,导致的不匹配。两者步调一致,就能避免类似的坑。
个人建议,在时间精力足够的条件下,项目和开发环境最好能跟着时代节奏比较好。举个例子,2021年了,有人还是喜欢用Photoshop cs5,殊不知Photoshop2020都有一键抠图的功能了。