Unity自动打包Android其实要比IOS容易得多,因为Android不用先生成java工程,然后在构建.apk包,我先说说Android打包的步骤。
1.把sdk拷贝至Plugins/Android下。
如下图所示,如果你做过Android源生开发,我相信下面的东西你不会陌生。可是如果你没做过Android原生开发,我还是详细说明以下。
AndroidManifest:这是Android程序必不可少的文件,这里记录着应用程序的启动Activity。Activity就是Android的一个界面,一般应用程序会有很多Acitivty,来回切换界面。但是游戏就不太一样了,因为游戏只需要一个Activity 一个View就可以了。(扯远了)
AndroidManifest:里面还记录着应用程序的权限,Service啊什么的,,有兴趣的同学可以谷歌搜一搜。
每次打包的时候Unity会用它默认的AndroidManifest,它默认的AndroidManifest在 unity.app/Contents/PlaybackEngines/AndroidPlayer下面。当你在进行打包apk的时候 unity会拷贝该路径下的所有参数。
在ProjectSetting里面勾选一些权限的时候,Unity会自动帮你修改AndroidManifest里面的权限,但是如果某个权限不能在Unity工程里面修改,那么就需要自己手动替换。如下图所示,我们把AndroidManifest放在Plugins/Android下面, 这样Unity在进行打包的时候就不会用它默认的,而是用我自己新写的打包。。这样就方便灵活很多了。。
bin:下面就记录着sdk用到的第三方jar
res:下面就是安卓的一些图片,资源啊什么。
你可以随便解开一个android的APK看看它的目录结构就明白了。。
这样在打包的时候unity就会自动把Plugins/Android下面的所有资源打包在你的APK里面了。但是如果你做渠道包的时候,每个包用的是不同的sdk,所以你需要在打包不同渠道的时候把相关的文件拷贝在Plugins/Android下面。
如下图所示,我在根目录下创建一个文件夹名子叫91,当我自动化打包的时候自动把91文件夹下面的资源先拷贝在Plugins/Android下面,然后在自动打包。。 打完包以后再把Plugins/Andoird文件夹清空即可。。
Ok上脚本。。代码和上一篇文章的第一步差不多,我就不多余注释,,执行下面shell脚本将自动打开unity,然后执行ProjectBuild.BuidForAndroid方法。。 project-$1 就是传入的参数。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#!/bin/sh #参数判断 if [ $# != 1 ];then echo "需要一个参数。 参数是游戏包的名子" exit fi #UNITY程序的路径# UNITY_PATH=/Applications/Unity/Unity.app/Contents/MacOS/Unity #游戏程序路径# PROJECT_PATH=/Users/MOMO/commond #在Unity中构建apk# $UNITY_PATH -projectPath $PROJECT_PATH -executeMethod ProjectBuild.BuildForAndroid project-$1 -quit echo "Apk生成完毕" |
在关闭unity的情况下运行。在命令行里面执行这一条脚本, 参数一个参数 91。
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 |
using System.Collections; using System.IO; using UnityEditor; using UnityEngine; using System.Collections.Generic; using System; class ProjectBuild : Editor{ //在这里找出你当前工程所有的场景文件,假设你只想把部分的scene文件打包 那么这里可以写你的条件判断 总之返回一个字符串数组。 static string[] GetBuildScenes() { List<string> names = new List<string>(); foreach(EditorBuildSettingsScene e in EditorBuildSettings.scenes) { if(e==null) continue; if(e.enabled) names.Add(e.path); } return names.ToArray(); } static void BuildForAndroid() { Function.DeleteFolder(Application.dataPath+"/Plugins/Android"); if(Function.projectName == "91") { Function.CopyDirectory(Application.dataPath+"/91",Application.dataPath+"/Plugins/Android"); PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Android, "USE_SHARE"); } string path = Application.dataPath +"/" + Function.projectName+".apk"; BuildPipeline.BuildPlayer(GetBuildScenes(), path, BuildTarget.Android, BuildOptions.None); } } |
程序会执行BuildForAndroid的方法,这里我把shell传入的参数取出来。根据传入的不同参数来初始化打包的一些设置。。
最终BuildPlayr就开始构建apk,第二个参数就是打包出apk保存的路径。 在打包之前你可以处理一些 游戏包名, 游戏icon 等等一些平台之间的特殊性 ,也可以设置一些 预定义标签,。
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 |
using UnityEngine; #if UNITY_EDITOR using UnityEditor; using UnityEditor.Callbacks; using UnityEditor.XCodeEditor; using System.Xml; #endif using System.IO; public static class XCodePostProcess { #if UNITY_EDITOR [PostProcessBuild (100)] public static void OnPostProcessBuild (BuildTarget target, string pathToBuiltProject) { if (target == BuildTarget.Android) { Function.DeleteFolder(Application.dataPath+"/Plugins/Android"); if(Function.projectName== "91") { //当我们在打91包的时候 这里面做一些 操作。 } } } #endif } |
在回到XUPortr里面,当Android打包完毕后,这里我们清空Plugins/Android文件夹。。或者你也可以做一些操作。。
Function.cs 用到的一个工具类
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 |
using UnityEngine; using System.Collections; using System.IO; public class Function { //得到项目的名称 public static string projectName { get { //在这里分析shell传入的参数, 还记得上面我们说的哪个 project-$1 这个参数吗? //这里遍历所有参数,找到 project开头的参数, 然后把-符号 后面的字符串返回, //这个字符串就是 91 了。。 foreach(string arg in System.Environment.GetCommandLineArgs()) { if(arg.StartsWith("project")) { return arg.Split("-"[0])[1]; } } return "test"; } } public static void DeleteFolder(string dir) { foreach (string d in Directory.GetFileSystemEntries(dir)) { if (File.Exists(d)) { FileInfo fi = new FileInfo(d); if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1) fi.Attributes = FileAttributes.Normal; File.Delete(d); } else { DirectoryInfo d1 = new DirectoryInfo(d); if (d1.GetFiles().Length != 0) { DeleteFolder(d1.FullName);////递归删除子文件夹 } Directory.Delete(d); } } } public static void CopyDirectory(string sourcePath, string destinationPath) { DirectoryInfo info = new DirectoryInfo(sourcePath); Directory.CreateDirectory(destinationPath); foreach (FileSystemInfo fsi in info.GetFileSystemInfos()) { string destName = Path.Combine(destinationPath, fsi.Name); if (fsi is System.IO.FileInfo) File.Copy(fsi.FullName, destName); else { Directory.CreateDirectory(destName); CopyDirectory(fsi.FullName, destName); } } } } |
如下图所示,脚本运行完毕,你打包的APK就静静的放在了这里,怎么样?简单吧?嘿嘿。。
注意事项:
1、因为你的工程可能比较大,如果IOS和Android同时打包的话切个平台都要半个多小时,我建议的svn在本地check out 两个工程,一个切在ios 一个切在Android 打包的时候分开打。
2.执行shell脚本的时候请关闭保存unity工程。
3.Android 因为不受证书的限制,我上传的工程建议你下载下来看看,肯定可以直接打出来包。。
4.我建议打包的机器使用mac。 因为windows不能打包IOS 而MAC可以同时 打包 IOS 和 Android
工程下载地址:http://pan.baidu.com/s/1o6OATcu
最后雨松MOMO祝大家学习愉快,哇咔咔。
- 本文固定链接: https://www.xuanyusong.com/archives/2748
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
大大 请问咱们的unity版本是多少呀 我导入到项目里说是无法解压压缩包 是不是我的unity版本太高导致的呢 unity版本 2021.3.5f1
unity2019 自动打包总是被SDK Tools out of date卡住,每次必须手动点击use highest,update没有反应,导致没法自动化,这是为什么呢
可以单独下载sdk
打包提示 Unable to locate Android NDK.
可是我再全局变量里配置了 ANDROID_NDK_HOME
你好,我想问下,为什么unity直接打出的包比用eclipse打出来的包大很多?我StreammingAsset下放的资源比较多。还有就是eclipse打出来的包比unity在启动的时候要慢很多,进入游戏后就正常了?
MOMO大神,自动打包时候keystore可以动态指定路径吗?如果可以是怎么动态指定的啊? u3d版本是5.2.4
可以指定
你好,我现在接sdk都是先从u3d导出android工程,然后在eclipse里做二次开发的。还有一种方法就是先从eclipse里写好然后导出jar包到u3d那边。第二种方法没试过,请问如果我有很多版本的sdk比如不同国家有不同的sdk,我又想做一键打包功能,用哪种方法好?
1.先把unity导出eclipse工程, 2.自动把sdk需要的jar脚本拷贝进去 3. 脚本自动修改.java里的代码, 其实就是修改文件。 4 用ant打包
嗯 现在流程差不多是这样,但还没能自动修改代码。多谢多谢~~
MOMO,你好,我现在将Unity项目移植到android项目内,但是总是运行就报错,根本运行不起来:W/System: ClassLoader referenced unknown path: /data/app/com.unity.demo9-1/lib/armE/Unity: Unable to find main 请问这个是什么问题????
请问MOMO大哥我的药怎么才能发布出apk游戏安装包呢
我在发布apk的时候发到一半就会提示尝试寻找一个正确的安卓设备,然后就停止了发布,
apk安装时会自动创建Applicatoin.persistenDataPath目录吗
也不算是自动创建,因为每个应用程序安装后都有 这样的读写目录。。。
厚脸皮来问一句,是否需要下载除了unity之外的其他软件,比如Android studio和SDK,刚接触不久,忘能恢复,谢谢
androidsdk肯要下载的 IDE我习惯用eclipse
momo,我游戏安装好的名字,都是我在unity里面打包时候的包名。我想给它去一个中文名,应该怎么做呀?
你好,我这边脚本打包的时候提示无法签名,应该跟keystore的选择和密码有关,请问这个要怎么设置呢?另外,ios里面会涉及到签名,请问又是怎样设置的呢?
请问ProjectBuild.cs要放在哪里?启动Unity后报错ProjectBuild. BuildForAndroid can not be found
雨松大大 我不想用unity自带的splash场景,怎么设置啊?