1. 程式人生 > >[Unity]Unity安卓一鍵打包

[Unity]Unity安卓一鍵打包

    因為之前在接平臺SDK的時候,為了後期打包方便,寫了個一鍵打包工具,後面平臺說要做融合SDK,那就意味著需要給遊戲aar包,突然發現白寫了。很傷心,就共享出來。只寫了安卓的一鍵打包,IOS的也是剛碰的,雖然IOS的SDK接好了,但也沒超過10天,所以還沒去弄。估計後面也不會去弄了。

    先來個簡短的

public static class AutoBuilder
{
    private const string startScenePath = "Assets/Resources/Scene/Main.unity";

    public static string[] GetScenePaths()
    {
        int count = 0;
        string[] scenes = new string[count];

        return scenes;
    }

    public static void CopyPlatformInfo(string platformSDKPath)
    {
        if (string.IsNullOrEmpty(platformSDKPath)) return;

        if(EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
        {
            if (Directory.Exists(AssetHelper.AndroidPluginsPath))
                Directory.Delete(AssetHelper.AndroidPluginsPath, true);
            if (Directory.Exists(platformSDKPath))
                ToolsWindow.CopyDirectory(platformSDKPath, AssetHelper.PluginsPath);
        }

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }

    public static void AutoBuildApp(string publisPath)
    {
        if(EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
        {
            BuildPipeline.BuildPlayer(GetScenePaths(), publisPath, BuildTarget.Android, BuildOptions.None);
        }
    }
}

    CopyPlatformInfo方法的主要功能就是拷貝不同平臺的配置檔案,為了方便,我是把當前Unity工程下的Plugins中的Android整個目錄刪除,再從配置好的SDK目錄下拷貝到Unity工程下的Plugins中,就是這麼簡單,不要忘了呼叫AssetDatabase.SaveAssets()和AssetDatabase.Refresh()這兩個介面。

    AutoBuildApp方法就不用解釋了,就官方的打包介面。

接下來的就是一個視窗類

public class PlatformInfo
{
    public string PlatformId;
    public string PlatformName;
    public string PlatformPath;
    public string PlatformBuildNameExt;
}

public static class AssetHelper
{
    public static string RootPath = Application.dataPath.Substring(0, Application.dataPath.Length - ("Assets".ToString().Length));
    public static string PluginsPath = Application.dataPath + "/Plugins";
    public static string AndroidPluginsPath = Application.dataPath + "/Plugins/Android";
    public static string BuildPath = RootPath + "/Builds/";
    public static string[] NeedDeletePath = { Application.dataPath + "/Plugins/x86" };
}

public class ToolsWindow : EditorWindow
{
    private bool bIsInit = false;
    public Dictionary<string, PlatformInfo> pInfoList = new Dictionary<string, PlatformInfo>();
    public Dictionary<string, bool> packSelectList = new Dictionary<string, bool>();
    private bool bIsShowLog = false;

    [MenuItem("Tools/打包工具")]
    static void Open()
    {
        GetWindow<ToolsWindow>("打包工具");
    }

    #region 方法
    public static List<string> ReadFileByLine(string filePath)
    {
        List<string> infoList = new List<string>();
        if (!File.Exists(filePath))
            return infoList;
        FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
        StreamReader streamReader = new StreamReader(fileStream);
        do
        {
            string lineStr = streamReader.ReadLine();
            if (lineStr == null || lineStr.Length == 0)
                break;
            if (!lineStr.Contains("#"))
                infoList.Add(lineStr);
        }
        while (true);
        fileStream.Close();
        streamReader.Close();
        return infoList;
    }

    /// <summary>
    /// 拷貝資料夾
    /// </summary>
    /// <param name="sourceDirectory"></param>
    /// <param name="destDirectory"></param>
    public static void CopyDirectory(string sourceDirectory, string destDirectory)
    {
        if (string.IsNullOrEmpty(sourceDirectory) || string.IsNullOrEmpty(destDirectory)) return;

        var sourceFilesPath = Directory.GetFileSystemEntries(sourceDirectory);
        for (int i = 0; i < sourceFilesPath.Length; ++i)
        {
            var sourceFilePath = sourceFilesPath[i];
            sourceFilePath = sourceFilePath.Replace("\\","/");
            var directoryName = Path.GetDirectoryName(sourceFilePath);
            var folders = directoryName.Split('/');
            var lastDirectory = folders[folders.Length - 1];
            var dest = destDirectory + "/" + lastDirectory;
            //Debug.LogError(directoryName + "----" + dest);
            if (File.Exists(sourceFilePath))
            {
                var sourceFileName = Path.GetFileName(sourceFilePath);
                if (!Directory.Exists(dest))
                {
                    Directory.CreateDirectory(dest);
                }
                //Debug.LogError(sourceFilePath + "----" + dest + sourceFileName);
                File.Copy(sourceFilePath, dest + "/" + sourceFileName, true);
            }
            else
                CopyDirectory(sourceFilePath, dest);
        }
    }

    public static string GetPublishPath(string PlatformBuildNameExt)
    {
        string publishPath = AssetHelper.BuildPath;
        if (!Directory.Exists(publishPath))
            Directory.CreateDirectory(publishPath);

        if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
        {
            publishPath += "Android/";
        }

        if (!Directory.Exists(publishPath))
            Directory.CreateDirectory(publishPath);

        if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
        {
            string timeExt = System.DateTime.Now.ToString("yyyyMMddHHmm");
            publishPath += "game" + "_" + PlatformBuildNameExt + "_" + timeExt + ".apk";
        }

        return publishPath;
    }
    #endregion

    void Init()
    {
        pInfoList.Clear();
        List<string> pInfoStrList = ReadFileByLine(AssetHelper.RootPath + "sdkconfig/PlatformInfo.txt");
        foreach(string pInfoStr in pInfoStrList)
        {
            int index = 0;
            string[] infoStr = pInfoStr.Split('|');
            if(infoStr != null)
            {
                PlatformInfo temp = new PlatformInfo();
                int length = infoStr.Length;
                
                if(length > index)
                {
                    temp.PlatformId = infoStr[index];
                    ++index;
                }
                if (length > index)
                {
                    temp.PlatformName = infoStr[index];
                    ++index;
                }
                if (length > index)
                {
                    temp.PlatformPath = infoStr[index];
                    ++index;
                }
                if (length > index)
                {
                    temp.PlatformBuildNameExt = infoStr[index];
                    ++index;
                }
                
                pInfoList.Add(temp.PlatformId, temp);
            }
        }

        bIsInit = true;
    }

    /// <summary>
    /// 開啟日誌
    /// </summary>
    /// <param name="bIsShow"></param>
    void SetLogging(bool bIsShow)
    {
        if(bIsShow)
        {
            PlayerSettings.SetStackTraceLogType(LogType.Assert, StackTraceLogType.Full);
            PlayerSettings.SetStackTraceLogType(LogType.Error, StackTraceLogType.Full);
            PlayerSettings.SetStackTraceLogType(LogType.Exception, StackTraceLogType.Full);
            PlayerSettings.SetStackTraceLogType(LogType.Log, StackTraceLogType.Full);
            PlayerSettings.SetStackTraceLogType(LogType.Warning, StackTraceLogType.Full);
        }
        else
        {
            PlayerSettings.SetStackTraceLogType(LogType.Assert, StackTraceLogType.None);
            PlayerSettings.SetStackTraceLogType(LogType.Error, StackTraceLogType.None);
            PlayerSettings.SetStackTraceLogType(LogType.Exception, StackTraceLogType.None);
            PlayerSettings.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
            PlayerSettings.SetStackTraceLogType(LogType.Warning, StackTraceLogType.None);
        }
    }

	void OnGUI()
    {
        if (!bIsInit || pInfoList.Count <= 0)
            Init();

        GUILayout.Label("平臺選擇(勾選的打包)");
        EditorGUILayout.BeginHorizontal();
        int index = 0;
        foreach (var pi in pInfoList)
        {
            if (pi.Value == null) continue;

            GUILayout.Label(pi.Value.PlatformName + ":" + pi.Value.PlatformId);
            bool bIsSelect = false;
            packSelectList.TryGetValue(pi.Value.PlatformId, out bIsSelect);
            bool check = EditorGUILayout.Toggle(bIsSelect);
            if (check != bIsSelect)
                packSelectList[pi.Value.PlatformId] = check;
            if((index + 1) % 4 == 0)
            {
                GUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
            }
            ++index;
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        bool bIsShow = bIsShowLog;
        bool bCheck = EditorGUILayout.Toggle("是否顯示日誌", bIsShow);
        if (bCheck != bIsShow)
            bIsShowLog = bCheck;
        SetLogging(bIsShowLog);
        EditorGUILayout.EndHorizontal();

        if (GUILayout.Button("發包"))
        {
            Config.useLuaAB = true;
            SDKManager.bIsTest = true;

            if (AssetHelper.NeedDeletePath.Length > 0)
            {
                foreach (var path in AssetHelper.NeedDeletePath)
                {
                    if (Directory.Exists(path))
                        Directory.Delete(path, true);
                }
            }
            
            if (packSelectList.Count <= 0)
            {
                Debug.LogError("請勾選需要釋出的平臺");
            }
            else
            {

                foreach (var selectInfo in packSelectList)
                {
                    if (selectInfo.Value == false || !pInfoList.ContainsKey(selectInfo.Key)) continue;
                    PlatformInfo temp = pInfoList[selectInfo.Key];
                    if (temp == null || string.IsNullOrEmpty(temp.PlatformPath)) continue;

                    AutoBuilder.CopyPlatformInfo(AssetHelper.RootPath + temp.PlatformPath);

                    AutoBuilder.AutoBuildApp(GetPublishPath(temp.PlatformBuildNameExt));
                }
            }
        }
    }
}

    有註釋的就不多介紹了,程式碼很簡單。

    PlatformInfo和AssetHelper這兩個類就不用解釋,一個儲存平臺資訊,一個則是安卓外掛目錄,需要刪除的資料夾等。

    ReadFileByLine函式的功能就是讀取儲存平臺資訊的txt檔案。

    GetPublishPath函式的功能就是生成apk目錄。

    Init函式的功能就是儲存平臺資訊。方便後面選擇要打什麼包。

    OnGUI都有文字介紹,也蠻清晰的,就不多說了。

相關推薦

[Unity]Unity打包

    因為之前在接平臺SDK的時候,為了後期打包方便,寫了個一鍵打包工具,後面平臺說要做融合SDK,那就意味著需要給遊戲aar包,突然發現白寫了。很傷心,就共享出來。只寫了安卓的一鍵打包,IOS的也是剛碰的,雖然IOS的SDK接好了,但也沒超過10天,所以還沒去弄。估計後面

修改IMEI號碼、修改串號工具,擼客族的必備

       很多擼客,有擼美團擼大眾的,還有各種擼客,以前很火,這些我都叫做擼客,也屬於網賺一族吧,之前在群裡很多新手都不懂如何擼,不知道如何修改手機IMEI串號,我給他們分享了能夠模擬手機串號的工具琢石模擬器,這也是擼客老手必備的工具,當然琢石模擬器自身的功能是保護手機

天鄂情,免費打包app,webapp線上製作平臺,打包ios

對比原生app高額的製作成本和運營成本,除錯複雜,app打包平臺橫空出世,免程式設計,網站一鍵生成app,各種jsapi介面,推送功能可以直接套用,成熟的平臺完美的為app開發者服務,即使菜鳥也能在十分鐘之內製作屬於自己的app,獨立後臺,更新方便。天鄂情官方網

HTML打包APK工具(應用APP)

工具簡介 “HMTL一鍵打包APK工具”可以把本地HTML專案或者網站打包為一個安卓應用APK檔案,無需編寫任何程式碼,支援在安卓裝置上安裝執行。 打包工具群:429338543 下載地址: 加群獲取最新軟體 軟體交流群:429338543 KRPan

Unity中的打包實現

unity開發中 在發包之前經常會做一些額外操作。比如打包assetbundle。使用lua的還會建立對應的wrap程式碼等。以及編譯完成後上傳assetbundle包到web伺服器。app到測試伺服器等 這些額外的動作會導致打包的碎片化。 於是寫了這麼一個一鍵打包的指令碼。實現不怎麼漂亮,好在完成了功能

Unity包 Android 所有錯誤解決方案大全(幾乎囊括所有打包錯誤 )

Unity打包出錯解決方案 本文提供全流程,中文翻譯。 Chinar 堅持將簡單的生活方式,帶給世人!(擁有更好的閱讀體驗 —— 高解析度使用者請根據需求調整網頁縮放比例) C

adt-bundlee-windows-x86-x64之開發環境打包下載

ADT-Bundle for Windows 是由Google Android官方提供的整合式IDE,已經包含了Eclipse,你無需再去下載Eclipse,並且裡面已集成了外掛,它解決大部分新手通

Unity打包為APK檔案(windows平臺)

網上關於一鍵打包的資料多不勝數,這篇文章只是本人的一個歸納總結,希望能讓新人們少走點彎路。 前一篇文章介紹瞭如何在windows下用批處理呼叫Unity方法,看這篇文章前請先看一下它。 工作流程: 1. 從Unity匯出Android專案(批處理呼叫unity實現) 2.

unity之——AssetBundle在平臺的打包與載入解析(超大一個坑!今天給填了)

最近一直在頭疼一個問題,自己寫的小Demo,利用AssetBundle動態載入的方式在安卓平臺顯示一個圖片的預設。一直不成功的原因是:因為載入路徑的問題,在安卓平臺下載入不出來assetBundle物件。我是用的AssetBundle.LoadFromFile()的方法載入的

Win7使用jenkins打包unity工程的apk包

環境:win7 一、寫unity打包指令碼 網上那些教程都太複雜了,又是build.xml又是properties檔案什麼的,一點都不適合菜鳥上手 新建一個txt檔案,新增以下程式碼: using UnityEditor; class MyEditorScript {  

Unity交互心得

capture ati unable persist 分享功能 ble eat 目錄 git 一 調用Android原生分享功能。 不需要網上說的在Android studio或者eclipse導出jar包到unity然後調用。只需要正常建立一個cs文件寫入以下代碼即可

unity接入SDK,與相互通訊

.接SDK是個什麼樣的活計? SDK的工作流程: 1. 從unity端出發,向安卓發起一系列的請求(unity call android)。 2. 安卓端收到unity端呼叫,然後在具體呼叫SDK的一系列介面(android內部呼叫) 3. SDK伺服器處理之後得到結果,再返回給安卓(網路通訊) 4

unity實現手機讀xml方法

直接上程式碼 string path = string.Empty; WWW www; if (Application.platform == RuntimePlatform.Android) { path = Appl

unity包及錯誤

一,安裝sdk,jdk, 分別點選download,去下載就好了。這裡sdk要翻牆。提供一個地址:http://www.androiddevtools.cn/,這裡可以下載舊的sdk以及as(android studio的縮寫)。sdk的安裝,可以通過as或者sdkMana

Unity釋出進行模型縮放和旋轉

using UnityEngine; using System.Collections; public class ScaleAndRotate : MonoBehaviour {     private Touch oldTouch1;  //上次觸控點1(手指1)  

unity釋出包路徑顯示錯誤

unity專案在windows下執行正常,進行安卓打包測試的時候發現以下錯誤 經過反覆查詢,最後發現竟然是因為打包的時候指定了錯誤的路徑 修改之後再次build仍然報錯如下:   最後在xlua的github中FAQ發現瞭解決之道,是因為有些函式被放在

Unity懶人福利————— 搭UI工具

RoadLun原創,轉載請宣告 眾所周知,搭UI是一件繁瑣無聊枯燥乏味的事情,具本博主見聞,很多公司會招妹子程式設計師專門搭UI和UI相關的邏輯。設定每個UI的錨點和座標真是一個繁重的工作。例如很多手遊的某一個選單欄下有許多子按鈕,某天策劃覺得這些按鈕的間距太小,這時候就需要程式設計師挨個調整,

Unity互動之拍照與相簿

參考連結: 準備環境,我的是unity4.7.1 和 AndroidStudio 首先匯入unity目錄的 classes.jar 包到 AndroidStudio的 libs 目錄下 然後設定 build.gradle 刪除activity_

Unity啟動外部APK,無需程式碼(轉載)

if (GUILayout.Button("LoadApk")) { openPackage("com.test.apk"); } } void openPackage(string pkgName) {

關於Unity釋出專案,拉起輸入法字為白色

今天專案在安卓測試的時候發現,登入驗證的Input視窗拉起的手機輸入法的字都是白色的。一般手機預設的輸入法都是白底黑字的,這就導致了輸入的文字在手機上的輸入法不顯示的bug。 一般而言,出現這種情況的原因是工程中某些SDK修改了AndroidManifast.xml的主題。 Andr