公司有的项目是用的 Unity 2020,之前一直用的是 2018 版导出 Android Studio,切换到 2020 后发现与之前的版本改动较大,于是踩到了不少的坑。
环境版本
NDK 版本:Unity 2018 用的是 r18b
版本,Unity 2020 用的是 r19
版本。
Gradle 版本:Unity 2018 最低版本是 5.1.1,Unity 2020 最低版本是 5.6.4。
导出工程报错,提示 build cannot be appended
或者 the build target does not support build appending
。 原因是 Unity 从 2019.4.14f1
版本开始修改了 Android Studio 导出的选项,如果使用 Gradle
来编译,首先需要设置 EditorUserBuildSettings.exportAsGoogleAndroidProject = true
,才能导出 Android Studio。其次将 BuildPlayerOptions
中移除 BuildOptions.AcceptExternalModificationsToPlayer
这个选项。
例如:
1 2 3 4 5 6 EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle; EditorUserBuildSettings.exportAsGoogleAndroidProject = true ; BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.options = BuildOptions.None | BuildOptions.Development; BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
导出报错,提示 `mainTemplate.gradle file is using the old aaptOptions noCompress property definition which does not include types defined by unityStreamingAssets constant. gradle 的 noCompress
中没有定义 unityStreamingAssets
里的文件后缀名。
Uniy 2018 中的 noCompress
是:
1 2 3 aaptOptions { noCompress = ['.unity3d' , '.ress' , '.resource' , '.obb' ] }
Unity 2020 中改成了:
1 2 3 4 aaptOptions { noCompress = ['.ress' , '.resource' , '.obb' ] + unityStreamingAssets.tokenize(', ' ) ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~" }
包含了 unityStreamingAssets
中的文件,`unityStreamingAssets
的定义在
gradle.properties` 文件中:
1 2 3 4 org.gradle.jvmargs=-Xmx4096M org.gradle.parallel=true android.enableR8=false unityStreamingAssets =.unity3d, test.txt
生成工程的路径变化 在 Unity 2018 中,假设设置工程路径为 ../ProjectPath
,生成出来的工程路径为 ../ProjectPath/ProjectName
,其中 ProjectName
是项目的名称。例如:
1 2 3 4 5 PlayerSettings.productName = "MyProject" ; BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.locationPathName = "../Path" ; BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
在 Unity 2020 中,假设设置工程路径为 ../ProjectPath
,生成出来的工程路径为 ../ProjectPath
,不会再带有项目名称了。例如:
1 2 3 4 5 PlayerSettings.productName = "MyProject" ; BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.locationPathName = "../Path" ; BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
生成的Android Studio 工程结构变化 Unity 2018 生成完的工程结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 - build.gradle // Assets/Plugins/Android/mainTemplate.gradle - gradle/ - gradle.properties - gradlew - libs/ // Assets/Plugins/Android/libs 目录下的 *.jar 和 *.aar 文件 - local.properties - proguard-unity.txt - setting.gradle // Assets/Plugins/Android/settingsTemplate.gradle - src/ - main/ - AndroidManifest.xml // Assets/Plugins/Android/AndroidManifest.xml - assets/ // Unity 生成的资源,Assets/Plugins/Android/assets,Assets/StreamingAssets 目录下的文件 - java/ // java 源码 - jniLibs/ // Assets/Plugins/Android/libs/armeabi/*.so 各个架构下的 so 文件 - res/ // Unity 生成,图标,游戏名,主题等 - unity-android-resources/ - AndroidManifest.xml - build.gradle // Assets/Plugins/Android/libTemplate.gradle - project.properties - res/ // Assets/Plugins/Android/res 目录下的文件
Unity 2020 生成完的工程结构如下:
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 - build.gradle // Assets/Plugins/Android/baseProjectTemplate.gradle - gradle/ - gradle.properties // Assets/Plugins/Android/gradleTemplate.properties - gradlew - launcher/ - build.gradle // Assets/Plugins/Android/launcherTemplate.gradle - src/ - main/ - AndroidManifest.xml // Assets/Plugins/Android/LauncherManifest.xml - res/ // Unity 生成,图标,游戏名,主题等 - local.properties - setting.gradle // Assets/Plugins/Android/settingsTemplate.gradle - unityLibrary/ - build.gradle // Assets/Plugins/Android/mainTemplate.gradle - libs/ // Assets/Plugins/Android/libs 目录下的 *.jar 和 *.aar 文件 - progurad-unity.txt - src/ - main/ - AndroidManifest.xml // Assets/Plugins/Android/AndroidManifest.xml - assets/ // Unity 生成的资源,Assets/Plugins/Android/assets,Assets/StreamingAssets 目录下的文件 - Il2CppOutputProject/ // Unity 生成,如果使用了 il2cpp 打包 - java/ // java 源码 - jniLibs/ // Assets/Plugins/Android/libs/armeabi/*.so 各个架构下的 so 文件 - jniStaticLibs/ // - res/ // Unity 生成 - unity-android-resources/ - AndroidManifest.xml // Unity 生成 - build.gradle // Assets/Plugins/Android/libTemplate.gradle - project.properties - res/ // Assets/Plugins/Android/res 目录下的文件
生成 apk 失败报错,提示 processReleaseResources
使用了 ./gradlew assembleRelease
命令后报错:
1 2 3 4 5 * What went wrong: Execution failed for task ':launcher:processReleaseResources'. > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade > AAPT2 aapt2-3.6.0-6040484-osx Daemon #0: Unexpected error during link, attempting to stop daemon. This should not happen under normal circumstances, please file an issue if it does.
原因是 StreamingAssets
底下的文件太多而导致 aapt2
报错,需要分别修改 launcher/build.gradle
和 unityLibrary/build.gradle
文件中的 aaptOptions.noCompress
选项:
1 2 3 4 aaptOptions { noCompress = ['.ress' , '.resource' , '.obb' ] + unityStreamingAssets.tokenize(', ' ) ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~" }
将后面的 unityStreamingAssets.tokenize(', ')
删除,在 noCompress
里加入 StreamingAssets
中出现的文件后缀名,例如:
1 2 3 4 aaptOptions { noCompress = ['.ress' , '.resource' , '.obb' , '.bundle' , '.unity3d' , '.txt' ] ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~" }
java 代码 UnityPlayerActivity
类Unity 2018 这个类在生成的 unity-classes.jar
中有,游戏主 Activity 可以直接继承。
Unity 2020 在生成的 unity-classes.jar
中没有这个类了,需要使用 Unity 生成出来的 java 文件中找到这个类。
参考链接