[Unity] Android全自動(dòng)打包生成apk

Unity自動(dòng)打包Android其實(shí)要比IOS容易得多,因?yàn)锳ndroid不用先生成java工程,然后在構(gòu)建.apk包,我先說(shuō)說(shuō)Android打包的步驟。

1.把sdk拷貝至Plugins/Android下。

如下圖所示,如果你做過(guò)Android源生開(kāi)發(fā),我相信下面的東西你不會(huì)陌生??墒侨绻銢](méi)做過(guò)Android原生開(kāi)發(fā),我還是詳細(xì)說(shuō)明以下。

AndroidManifest:這是Android程序必不可少的文件,這里記錄著應(yīng)用程序的啟動(dòng)Activity。Activity就是Android的一個(gè)界面,一般應(yīng)用程序會(huì)有很多Acitivty,來(lái)回切換界面。但是游戲就不太一樣了,因?yàn)橛螒蛑恍枰粋€(gè)Activity 一個(gè)View就可以了。(扯遠(yuǎn)了)

AndroidManifest:里面還記錄著應(yīng)用程序的權(quán)限,Service啊什么的,,有興趣的同學(xué)可以谷歌搜一搜。

每次打包的時(shí)候Unity會(huì)用它默認(rèn)的AndroidManifest,它默認(rèn)的AndroidManifest在 unity.app/Contents/PlaybackEngines/AndroidPlayer下面。當(dāng)你在進(jìn)行打包apk的時(shí)候 unity會(huì)拷貝該路徑下的所有參數(shù)。

在ProjectSetting里面勾選一些權(quán)限的時(shí)候,Unity會(huì)自動(dòng)幫你修改AndroidManifest里面的權(quán)限,但是如果某個(gè)權(quán)限不能在Unity工程里面修改,那么就需要自己手動(dòng)替換。如下圖所示,我們把AndroidManifest放在Plugins/Android下面, 這樣Unity在進(jìn)行打包的時(shí)候就不會(huì)用它默認(rèn)的,而是用我自己新寫(xiě)的打包。。這樣就方便靈活很多了。。

bin:下面就記錄著sdk用到的第三方j(luò)ar

res:下面就是安卓的一些圖片,資源啊什么。

你可以隨便解開(kāi)一個(gè)android的APK看看它的目錄結(jié)構(gòu)就明白了。。


這樣在打包的時(shí)候unity就會(huì)自動(dòng)把Plugins/Android下面的所有資源打包在你的APK里面了。但是如果你做渠道包的時(shí)候,每個(gè)包用的是不同的sdk,所以你需要在打包不同渠道的時(shí)候把相關(guān)的文件拷貝在Plugins/Android下面。

如下圖所示,我在根目錄下創(chuàng)建一個(gè)文件夾名子叫91,當(dāng)我自動(dòng)化打包的時(shí)候自動(dòng)把91文件夾下面的資源先拷貝在Plugins/Android下面,然后在自動(dòng)打包。。打完包以后再把Plugins/Andoird文件夾清空即可。。


Ok上腳本。。代碼和上一篇文章的第一步差不多,我就不多余注釋?zhuān)?,?zhí)行下面shell腳本將自動(dòng)打開(kāi)unity,然后執(zhí)行ProjectBuild.BuidForAndroid方法。。?project-$1 就是傳入的參數(shù)。。

#!/bin/sh

#參數(shù)判斷??

if [ $# != 1 ];then??

????echo "需要一個(gè)參數(shù)。 參數(shù)是游戲包的名子"??

????exit????

fi??

#UNITY程序的路徑#

UNITY_PATH=/Applications/Unity/Unity.app/Contents/MacOS/Unity

#游戲程序路徑#

PROJECT_PATH=/Users/MOMO/commond

#在Unity中構(gòu)建apk#

$UNITY_PATH -projectPath $PROJECT_PATH -executeMethod ProjectBuild.BuildForAndroid project-$1 -quit

echo "Apk生成完畢"

在關(guān)閉unity的情況下運(yùn)行。在命令行里面執(zhí)行這一條腳本, 參數(shù)一個(gè)參數(shù) 91。

using System.Collections;

using System.IO;

using UnityEditor;

using UnityEngine;

using System.Collections.Generic;

using System;


class ProjectBuild : Editor{


//在這里找出你當(dāng)前工程所有的場(chǎng)景文件,假設(shè)你只想把部分的scene文件打包 那么這里可以寫(xiě)你的條件判斷 總之返回一個(gè)字符串?dāng)?shù)組。

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);

}

}

程序會(huì)執(zhí)行BuildForAndroid的方法,這里我把shell傳入的參數(shù)取出來(lái)。根據(jù)傳入的不同參數(shù)來(lái)初始化打包的一些設(shè)置。。

最終BuildPlayr就開(kāi)始構(gòu)建apk,第二個(gè)參數(shù)就是打包出apk保存的路徑。 在打包之前你可以處理一些 游戲包名, 游戲icon 等等一些平臺(tái)之間的特殊性 ,也可以設(shè)置一些 預(yù)定義標(biāo)簽,。

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")

???? {

???????????? //當(dāng)我們?cè)诖?1包的時(shí)候 這里面做一些 操作。


}

}

????}

????#endif

}

?在回到XUPortr里面,當(dāng)Android打包完畢后,這里我們清空Plugins/Android文件夾。?;蛘吣阋部梢宰鲆恍┎僮?。。

Function.cs 用到的一個(gè)工具類(lèi)

using UnityEngine;

using System.Collections;

using System.IO;

public class Function??{


//得到項(xiàng)目的名稱(chēng)

public static string projectName

{

get

{

//在這里分析shell傳入的參數(shù), 還記得上面我們說(shuō)的哪個(gè) project-$1 這個(gè)參數(shù)嗎?

//這里遍歷所有參數(shù),找到 project開(kāi)頭的參數(shù), 然后把-符號(hào) 后面的字符串返回,

//這個(gè)字符串就是 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);

}

}

}

}

如下圖所示,腳本運(yùn)行完畢,你打包的APK就靜靜的放在了這里,怎么樣?簡(jiǎn)單吧?嘿嘿。。

注意事項(xiàng):

1、因?yàn)槟愕墓こ炭赡鼙容^大,如果IOS和Android同時(shí)打包的話(huà)切個(gè)平臺(tái)都要半個(gè)多小時(shí),我建議的svn在本地check out 兩個(gè)工程,一個(gè)切在ios 一個(gè)切在A(yíng)ndroid ?打包的時(shí)候分開(kāi)打。

2.執(zhí)行shell腳本的時(shí)候請(qǐng)關(guān)閉保存unity工程。

3.Android 因?yàn)椴皇茏C書(shū)的限制,我上傳的工程建議你下載下來(lái)看看,肯定可以直接打出來(lái)包。。

4.我建議打包的機(jī)器使用mac。 因?yàn)閣indows不能打包IOS 而MAC可以同時(shí) 打包 IOS 和 Android

工程下載地址:http://pan.baidu.com/s/1o6OATcu

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容