最開始有写打包工具的想法,是由于看到《啪啪三国》王伟峰分享的一张图,他们有一个专门的“工具程序猿”开发各种工具。
(ps:说起来这个王伟峰和他的创始团队成员,曾经跟我是同一个公司的,公司名字就不透露了,仅仅是当时在不同的部门。相互不认识)。正好我们项目也到了后期,该准备接入渠道了。于是,我就着手写我们的打包工具。约定一下,下文中。平台是指操作系统平台,比方iOS、Android、WP8、Metro;渠道是指公布渠道。比方App Store、WP8商店、360、91、小米等。
上海火溶网络CEO王伟峰分享的《啪啪三国》打包工具
过程
从过程上。主要分为下面几步:
1. 资源准备。
2. 由Unity生成project;
3. 生成安装包;
4. 资源恢复。
详细到平台和渠道,会有一些细微差异,以下详细说。
WP8打包
这个是第一个写的,由于不涉及渠道,相对来说最简单。从下午4点,写到晚上9点多,时间大部分花在处理一些细节上。
第一步,资源相关的准备。我们是做了动态更新的,所以生成project之前。要先从Unity里删去更新的资源,这样打出的包更小。ps:事实上这一步之前,我们会先打更新包。关于资源打包与更新。我另写一篇文章介绍。另外,跟各个平台交互,我们写了插件,比方,内嵌web功能,Unity是没有的,要调用系统的api来做。
就是这么一个再普通只是的插件。让我花了大量时间处理。由于Unity经常load别的平台文件夹下的插件。比方,我有一个插件Platform.dll。依照Unity的官方文档。应该放到“Plugins/平台/”文件夹下,生成WP8project的时候,Unity应该选择Plugins/WP8/Platform.dll载入;打android包的时候,应该载入Plugins/Android/Platform.dll。可是遗憾的是。Unity不是这样,我打WP8的时候。它经常去载入Android文件夹下的插件。这个问题的解决办法,我一直没有查到,希望了解的朋友指教。为了解决问题,我就在打包的时候。把非当前平台文件夹下的插件删除,打好包之后,再恢复。
另外,还要删除上一次打包生成的文件。
第二步。生成project。这个没什么好说的。就是Unity的API调用,比方,BuildPipeline.BuildPlayer(BuildScenes, BuildPath, BuildTarget.WP8Player, BuildOptions.None);
第三步,生成安装包。在生成包之前。要替换一些Unity生成的文件,比方。MainPage.xaml/.cs,由于我们为了操作内嵌web,做了WP8特性的ApplicationBar。我们配置好的WMAppManifest.xml。友盟统计要求初始化必须在App.xaml.cs中,WP8projectAssets/文件夹下的Icon等。然后,依据须要改动project文件,比方,我们做了WP8的ApplicationBar。须要在打包工具里把相关的资源索引加入到project文件里。然后,就能够调用cmd来生成apk安装包了。
cmd主要是调用vs的命令,生成apk,调用vs安装文件夹下的devenv.exe,配置一下devenv.exe的參数就能够了。这里有一个须要注意的地方是,Build选项要选择Master,而不是Release。Release版本号有"profiler support"。Master才是公布用的。
第四步,资源恢复。包已经打好了。为了接下来打别的平台或渠道的包,恢复资源。比方,恢复更新的资源、各平台插件等。
Android打包
Android打包麻烦一些,不是由于渠道多。而是由于有的渠道有一些特殊需求。过程类似。以下主要说不同的地方。
第一步,资源相关的准备。跟WP8打包不同的是。Android是多渠道,要处理各个渠道的资源。
我最開始把全部渠道sdk相关的资源和代码。都放到Unity的Plugins/文件夹以下,比方Plugins/Android360、Plugins/Android91、Plugins/AndroidXiaoMi等,每次打包的时候,资源准备阶段先删除全部非当前渠道相关的内容,然后把当前渠道的文件夹名改动为Plugins/Android,打完包再删除Plugins/Android,然后调用svn update更新全部删除的内容。
写完之后,打一个包。ok。
当时接了11个渠道,然后我点了一下“Build All”。Build过程非常慢,由于有大量的散文件,svn update要几分钟。Unity import进来这些资源也要一些时间。并且,当打到第四、第五个包的时候。Unity import资源的时候,经常会报错。可能是由于磁盘上的文件与Unity的缓存文件之间同步的时候异常。这样打包太慢了。也无法做到一键打几十个包。后来,我想到把全部渠道文件放到Unity Assets文件夹外,这样,须要哪个sdk就copy进来哪个,打完包delete就能够了。不用svn update。也不须要Unity每次import大量的散文件。打包效率提高了几倍,并且。一键出十几个包,也没有遇到过Unity报错。
第二步,生成project。这个地方,我是走了一些弯路的。
最開始。我没有生成Androidproject,而是直接Build出来apk,这种优点是快。依据測试。3分钟多能够生成一个。而生成project之后再Build出apk,时间翻了一倍。
可是,各个渠道的sdk的特殊性,造成这种方式后来出几次问题。
第一次。接sdk的同学说,有的渠道要求独立的icon或splash。我想这个简单。用aapt直接操作生成apk,改动里面的内容。然后又一次签名就能够了。很快,又方便。
第二次,接百度多酷的同学说,用打包工具生成的apk,充值支付的时候。假设选择银联支付,会crash。
而先Build出project。然后用Eclipse编project生成的apk没问题。我细致对照了两个apk,发现直接生成的apk里,比project生成的apk里,res/drawable/文件夹下少了几个文件,data.bin/data_high.bin/data_low.bin/mobilepayplugin.bin,我怀疑是Unity直接生成apk的时候,过滤掉了这些文件。而生成project的时候没有过滤。什么原因?这个也好解决。找到缺少的文件。用aapt加进去。
后来,当乐、Oppo都须要在打包工具里增加相同的几个bin文件。
这样解决,不是好方法。可是攻克了问题。可是,后来Oppo的同学反馈说,我们的包打开的Oppo登录界面是全屏的,而实际应该是弹出窗体样式。这说明,打包的时候。可能有些界面布局文件,没有打进去。可是。这次。我没法通过对照两种方式生成的apk。找缺少哪个文件了,由于全部的资源文件,都打到resources.arsc里面了。这时,我认为这样的出现故障解决这个问题的思路是不正确的,应该从根本上拒绝出问题。然后。我又一次写了Android打包工具,先生成project。然后用Ant Build出apk。假设哪个渠道有特殊需求。在build apk之前操作project,比方替换icon、splash。当然,这样做打包过程变成了,慢了一半。
第三步。生成安装包。这个没什么好说的,就是Ant、sign、zipalign等。
另外。我们的运营有一个特殊的需求。他们投放渠道,分两种方式:一种是接渠道sdk。第二种是仅仅购买流量,不接sdk。针对第二种方式,我打包的时候,仅仅打一个包,然后,为了统计区分投放的渠道。对于生成的这个包,复制一份然后改动包里的配置文件,就能够了。不须要反复生成多次包。这样,十几秒就能够出一个包。我打包工具里的“SPP渠道包”这个button,就是是单独生成这样的渠道包的。
第四步,资源恢复。由于WP8就一个渠道,所以打完WP8包,就要直接恢复全部资源。而Android渠道众多。为了更快,有些资源是不须要恢复的,比方我们更新的内容。仅仅须要打全然部Android包之后,恢复一次就能够了。
iOS打包
写完WP8和Android打包工具后,我不想再做反复的工作了。就写了一份具体的文档。然后交给一个小伙伴。让他參考WP8和Android的代码,写iOS的打包工具,也是想让他锻炼、学习一下。结果。悲剧无比。!!
由于代码是非常类似的。并且我给他具体讲了怎么做,iOS也仅仅有3个渠道,他须要写的代码不超过50行,shell脚本预计在30行以内。这个我本来预估1-2天。最多3天能够做完的工作。他要了一周。而最后,他做了一月有余%>_<%
后来。发现有一个第三方工具。XUPorter,能够方便的编辑framework、plist甚至obj-c代码。有了它再配合写点shell脚本,iOS打包非常easy。
其他
我最開始写工具的时候。打包操作入口用的是[MenuItem(...)],操作button在Unity左上的菜单条。做出来的打包工具操作界面是这种:
我不知道大家有没有发现有什么问题。
问题就是:每次加渠道,我都要在代码里加入菜单项。比方,今天加入91渠道,在代码里加入:
[MenuItem("Build/Build Android Player/91")]
static void BuildAndroid91Player() {
// do something ...
}
明天加入了360渠道:
[MenuItem("Build/Build Android Player/360")]
static void BuildAndroid360Player() {
// do something ...
}
假设有几十个。甚至一两百个渠道怎么办?每次都改动代码?NO!ps:我们公司有一款产品真的接了一百多个渠道。
可是,在函数之外,怎样读配置对C#的属性[MenuItem(...)]做赋值处理?我还抱着一点侥幸查了一些资料,这是根本不可能的。
后来,我想起来之前看到的王伟峰分享那张图:
这张图尽管非常模糊,可是细致看看,我看出来他们的打包工具操作入口。不是在Unity 顶部的菜单条。而是在Inspector中。了解了在哪里写。实现就非常easy了,建一个Prefab就能够了。这样,以后新加入渠道,接入的同学仅仅须要依照我规定的格式,在配置文件中加一行渠道信息就能够了。改动后打包工具操作界面:
我们的打包工具操作入口
Refreshbutton是改动渠道配置文件之后。又一次读取配置文件。
Build Patch以下的几个button是打各平台的更新包,动态更新用的AssetBundle。
Build Player以下button式打各平台、各渠道的安装包。能够一键出某个包。或者一键出某平台的全部包。这里我没有做一键出全部平台的包。由于我们没有这个需求。假设要做,出完一个平台的包之后,切换一下平台就能够了(EditorUserBuildSettings.SwitchActiveBuildTarget(xxx))。
可是,注意不要Switch之后马上打新平台的包。而应该在回调接口里做,activeBuildTargetChanged。
Unity相关文章:Unity优化总结、Unity3D图形性能优化、Unity自己主动打包工具——Mac上打包android
转载请注明出处: http://blog.csdn.net/ynnmnm/article/details/36774715。作者:夜风。