介绍
官网介绍:
UWA旨在诊断与优化游戏和VR项目开发过程中潜在的运行性能问题,帮助项研发团队快速检测项目运行时的性能瓶颈,高效定位问题根源,及时反馈针对瓶颈问题的深度分析和解决方法。
UWA 提供两种 SDK,一种用来提交后测试,一种本地测试后提交。但是这两种 SDK 内容不同,打包时不能放在一起,需要分开打包。
另外,由于 UWA 主要用作测试,因此不想将资源放到项目内,否则打包时会有多余资源,增大包体。
因此最终的需求就是可以一键自动打包。
环境
- macOS 10.14.6
- Unity 5.6.6f2
- UWA v1.2.3
- UWA GOT v1.2.9
手动流程
测试
首先手动打包一次,了解整个流程并测试打出的包是否正常:
- 导入 UWA 资源包
- 在初始化场景中增加 UWA Prefab
- 修改项目设置
- 打包
确定好流程后就可以编写编辑器脚本初步集成了。
编辑器脚本
由于需要导入资源包之后再进行集成,尝试使用 AssetDatabase.importPackageCompleted
设置导入完成后回调,结果发现由于 UWA 中带有 DLL,导入时会导致重新编译,因此在导入完成回调没有执行。
尝试将脚本放在 Assets/Plugins/Editor
目录中优先编译不行。
尝试 EditorApplication.LockReloadAssemblies();
之后处理,等待处理完成后调用 EditorApplication.UnlockReloadAssemblies();
恢复,测试发现 API 无法阻止导入 Package 之后的编译。
最终需要在构建流程中将其拆分为两步,第一步导入 Package,第二步集成。必须手动点击,等待导入与编译完成之后再执行下一步。
自动流程
需要根据项目需要增加自动打包流程。
导入资源包
Unity Package
UWA 以 Unity Package 发布资源包。
尝试在启动 Unity 时指定 -importpackage path
参数来导入资源,测试后发现未导入资源。
又尝试运行 Unity 后使用 AssetDatabase.ImportPackage
API 导入资源包,结果还是无法导入资源。
Zip
最终尝试使用 zip 文件存储 UWA 资源,同时将不需要的 meta 文件删除,如 Plugins.meta
Plugins/Android.meta
。
使用命令行压缩:
1
|
zip -r ../UWAv1.2.3_Android.zip .
|
注意:
- 不要使用软件压缩完成后再手动打开压缩包删除不用的文件,使用 SharpZipLib 解压时会有报错(如 eZip)。
- 不要使用 macOS 右键菜单自带的压缩功能,因为会加入无用的
__MACOSX
目录。
SharpZipLib
推荐使用的 FastZip
无法正确在 macOS 上解压目录,因此需要使用普通方式解压,具体参考:
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
|
public static void ExtractZipFile(string archiveFilenameIn, string outFolder) {
ZipFile zf = null;
try {
var fs = File.OpenRead(archiveFilenameIn);
zf = new ZipFile(fs);
foreach (ZipEntry zipEntry in zf) {
if (!zipEntry.IsFile) {
continue; // Ignore directories
}
string entryFileName = zipEntry.Name;
byte[] buffer = new byte[4096]; // 4K is optimum
var zipStream = zf.GetInputStream(zipEntry);
// Manipulate the output filename here as desired.
string fullZipToPath = Path.Combine(outFolder, entryFileName);
string directoryName = Path.GetDirectoryName(fullZipToPath);
if (!string.IsNullOrEmpty(directoryName) && directoryName.Length > 0)
Directory.CreateDirectory(directoryName);
using (var streamWriter = File.Create(fullZipToPath)) {
StreamUtils.Copy(zipStream, streamWriter, buffer);
}
}
} finally {
if (zf != null) {
zf.IsStreamOwner = true; // Makes close also shut the underlying stream
zf.Close(); // Ensure we release resources
}
}
}
|
修改配置
按照文档要求直接修改配置即可:
1
2
3
4
5
6
7
8
|
public static void ChangeBuildSettings()
{
EditorUserBuildSettings.development = true;
PlayerSettings.Android.forceSDCardPermission = true;
PlayerSettings.SetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup,
ScriptingImplementation.Mono2x);
AssetDatabase.SaveAssets();
}
|
撤消导入资源包
在打包完成后需要恢复现场,因此将刚才解压出来的 UWA 资源删除掉,只需要遍历压缩包,将对应的文件删除即可。
正确做法是在解压前先保存要被覆盖的文件,撤消时恢复被覆盖的文件。这里并没有非常严谨,考虑到 UWA 使用的路径几乎不存在同名的其他资源。
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
|
public static void RemoveExtractedFiles(string archiveFilenameIn, string outFolder) {
ZipFile zf = null;
try {
var fs = File.OpenRead(archiveFilenameIn);
zf = new ZipFile(fs);
foreach (ZipEntry zipEntry in zf) {
if (!zipEntry.IsFile) {
continue; // Ignore directories
}
string entryFileName = zipEntry.Name;
string fullZipToPath = Path.Combine(outFolder, entryFileName);
if (File.Exists(fullZipToPath))
{
File.Delete(fullZipToPath);
}
}
} finally {
if (zf != null) {
zf.IsStreamOwner = true; // Makes close also shut the underlying stream
zf.Close(); // Ensure we release resources
}
}
}
|
结果
按照以上方式处理后就可以将其集成到打包方法内,可以结合 Jenkins 自动构建,而且可以同时打包 UWA 线上测试包与线下测试包。