Unity 打包 Apk 研究
Unity 打包 Apk 研究
Part 1:Unity 构建 Android的项目结构
Unity 构建 Android 主要由两个module 组成
- launcher
- unityLibrary
游戏代码(C# 脚本)和大部分插件都位于 unityLibrary 模块中,而 mainTemplate.gradle 正是用来配置这个模块的。launcherTemplate.gradle 只配置那个启动游戏的“空壳”应用。
Unity 的工作流程
1,生成临时 Android Gradle 项目
2,填充模板
3,变量替换 VARIABLE_NAME,替换为 Player Settings 中配置的值
4,调用 Gradle 执行编译,生成 APK 或 AAB
| 占位符变量 (在 .gradle 文件中) | 对应的 Unity Player Setting | 示例值 |
|---|---|---|
**APPLICATION_ID** | Package Name (包名) | com.mycompany.mygame |
**BUNDLE_VERSION_CODE** | Bundle Version Code(内部版本号) | 1, 2, 10 |
**VERSION_NAME** | Version (外部版本名) | 1.0, 2.1.3 |
**MIN_SDK_VERSION** | Minimum API Level (最低 API 级别) | 22 |
**TARGET_SDK_VERSION** | Target API Level (目标 API 级别) | 33 |
**UNITY_PLAYER_NAME** | Product Name (产品名称) | My Awesome Game |
**UNITY_COMPANY_NAME** | Company Name (公司名称) | My Company |
**SPLITS_ENABLED** | Split APKs by architecture(ARMv7, ARM64) | true 或 false |
**IL2CPP_DEVELOPMENT_BUILD** | Development Build (开发构建) | true 或 false |
Part 2: 如何生成和使用自定义 Gradle 模板?
- 打开 Player Settings:
Edit > Project Settings > Player。 - 切换到 Android 标签页 🤖。
展开 Publishing Settings:- 在这里,你会看到几个用于自定义构建的选项。勾选它们:
- Custom Main Manifest -> 生成
AndroidManifest.xml - Custom Main Gradle Template -> 生成
mainTemplate.gradle - Custom Launcher Gradle Template -> 生成
launcherTemplate.gradle - Custom Base Gradle Template -> 生成
baseProjectTemplate.gradle - Custom Gradle Settings Template - > 生成 settingsTemplate.gradle
- 其他的根据项目需要生成
- Custom Main Manifest -> 生成
- 核心就是将导出 Android Project中的资源打包,copy 到 Unity Assets/Plugins/Android中
Part 3: 标准的自定义 build.gradle 配置是什么样的?
1. mainTemplate.gradle - 核心模块配置
这个文件对应的是 unityLibrary 模块的 build.gradle。绝大多数自定义需求,比如添加依赖库,都在这里完成。 一个标准的带有注释的 mainTemplate.gradle 如下:
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// mainTemplate.gradle (for unityLibrary module)
// 声明这是一个 Android 库模块
apply plugin: 'com.android.library'
// (可选) 如果你使用 Kotlin,需要添加这个插件
// apply plugin: 'kotlin-android'
dependencies {
// Unity 默认的依赖
implementation fileTree(dir: 'libs', include: ['*.jar'])
// ============== 自定义区域开始 ==============
// 在这里添加你的原生 Android 库依赖
// 例如,添加 Google Play Core 库
// implementation 'com.google.android.play:core:1.10.3'
// 例如,添加一个第三方广告 SDK
// implementation 'com.some.ad.sdk:sdk-core:3.2.1'
// ============== 自定义区域结束 ==============
**DEPS** // <-- 这个占位符很重要,Unity 会用它来注入其他内部依赖,必须保留!
}
android {
// 编译用的 SDK 版本
compileSdkVersion **SDK_VERSION**
// 构建工具版本
buildToolsVersion '**BUILD_TOOLS_VERSION**'
// 默认配置块,这里的变量会被 Unity 替换
defaultConfig {
// 使用 Unity 的包名占位符
// 注意:库模块通常不设置 applicationId,但如果设置了,它应该与主模块一致
// applicationId '**APPLICATION_ID**'
// 使用 Unity 的最低/目标 SDK 版本占位符
minSdkVersion **MIN_SDK_VERSION**
targetSdkVersion **TARGET_SDK_VERSION**
// 使用 Unity 的版本号占位符
versionCode **BUNDLE_VERSION_CODE**
versionName '**VERSION_NAME**'
consumerProguardFiles 'proguard-unity.txt', 'proguard-user.txt'
}
// 设置 Java 源码的兼容性
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// Unity 自动生成的签名配置,让它保持原样
signingConfigs {
release {
storeFile file(project.property('unity.keystore.path'))
storePassword project.property('unity.keystore.password')
keyAlias project.property('unity.keyalias.name')
keyPassword project.property('unity.keyalias.password')
}
}
// 构建类型配置
buildTypes {
debug {
minifyEnabled false
debuggable true
}
release {
// 使用 Unity 的签名配置
signingConfig signingConfigs.release
minifyEnabled true // 开启混淆和压缩
// ProGuard 规则文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt', 'proguard-user.txt'
}
}
// aapt 选项,保持默认
aaptOptions {
noCompress = ['.unity3d', '.ress', '.resource', '.obb'**NO_COMPRESS_EXTENSIONS**]
ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*~:!*.bak:!*.orig:!*.*.meta:"
}
}
Q&A
1.Unity 导出 Android 继承GameActivity的启动类?
- 第一次导出Unity 的 AndroidProject 项目默认的启动类和现在导出的 Unity 默认启动类有差异了? Unity 版本2023.2.20f1c1 系统 Mac
- 当前导出的项目
- Unity 默认使用的启动类是 com.unity3d.player.UnityPlayerGameActivity
- UnityPlayerGameActivity 继承的是GameActivity,在类库’androidx.games:games-activity:3.0.0’中
- 首次导出的
- com.unity3d.player.UnityPlayerActivity
- UnityPlayerActivity 默认继承的是 Activity,module项目 unitylibrary没有引入其他类库
参考官方文档了解更多细节。
- Unity → File → Build Settings → Player Settings → Player → Other Settings
- 找到 Application Entry Point
- Activity 采用 Activity 方式,也就是com.unity3d.player.UnityPlayerActivity,默认继承 Activity
- GameActivity,默认导出三方库androidx.games:games-activity:3.0.0,默认继承 GameActivity
2.Unity 打包 apk 时,合并 AndroidManifest.xml时报错?
- 无法自动解析并合并 AAR 与远程依赖库中的 AndroidManifest.xml,至少目前是没有解析合并入 LauncherAndroidManifest.xml 中?
- 是 LauncherManifest.xml 中 Application 标签中定义的 tools:node=”replace” 导致放弃了其他非主 module 中的 AndroidManifest.xml 合并
- 解决方案是不能使用 tools:node=”replace”属性,将默认添加的那个 MAIN 入口类设置属性 tools:node=”remove” 即可
1 2 3
<activity android:name="com.unity3d.player.UnityPlayerActivity" tools:node="remove" />
本文由作者按照 CC BY 4.0 进行授权