1. 程式人生 > 其它 >命令列構建Unity專案

命令列構建Unity專案

自動任務構建

通常可以在桌面雙擊 Unity 圖示,啟動程式,但是,也可以通過命令列(例如,MacOS 終端或 Windows Command 視窗)執行程式。若使用這種方式啟動 Unity,它將可以接受啟動命令和資訊,這將非常有助於測試套件、自動構建和其他製作任務。

在 MacOS 中,可以在終端 (Terminal) 輸入以下內容,啟動 Unity:

/Applications/Unity/Unity.app/Contents/MacOS/Unity

而在 Windows 中,應在 cmd 視窗輸入:

"C:\Program Files (x86)\Unity\Editor\Unity.exe"

獨立版 Unity 遊戲可以用相同的方式啟動。

Unity命令列引數

如上所述,在啟動編輯器和構建遊戲時,也可以選擇性地使用其他命令和資訊。使用以下命令列引數並可達到這一目的:

官方文件引數說明:

Unity 編輯器命令列引數

Unity 獨立播放器命令列引數

-batchmode

在批處理模式下執行Unity。應始終與其他命令列引數一起使用,因為它確保不會彈出視窗,無需任何人為的干預。當指令碼程式碼在執行過程中發生異常,資源伺服器更新失敗或其他操作失敗時Unity將立即退出,並返回程式碼為1。請注意,在批處理模式下, Unity將向控制檯傳送輸出版本最小的日誌。當然,日誌檔案將包含完整的日誌資訊。

-quit

其他命令執行完畢後將退出Unity編輯器。請注意,這可能會導致錯誤訊息被隱藏(但他們將顯示在Editor.log檔案)

-createProject <pathname>

根據提供的路徑建立一個空專案

-projectPath <pathname>

開啟指定路徑的專案

-logFile <pathname>

指定 Unity 寫入編輯器或 Windows/Linux/OSX 獨立日誌檔案的位置

-exportPackage <exportAssetPath1 exportAssetPath2 ExportAssetPath3 exportFileName>

匯出一個包,給定一個路徑(或一組給定的路徑)。在本例中,exportAssetPath是要從 Unity 專案匯出的資料夾(相對於 Unity 專案根目錄),exportFileName是包名稱。此選項一次僅匯出整個資料夾。您通常需要將此命令與-projectPath引數一起使用

-executeMethod <ClassName.MethodName>

一旦 Unity 開啟專案,並且在可選的資​​產伺服器更新完成後,立即執行靜態方法。您可以將其用於諸如持續整合、執行單元測試、構建或準備資料之類的任務。

要從命令列程序返回錯誤,請丟擲導致 Unity 以返回程式碼 1 退出的異常,或者使用非零返回程式碼呼叫EditorApplication.Exit

要傳遞引數,請將它們新增到命令列並使用System.Environment.GetCommandLineArgs.要使用-executeMethod,您需要將封閉指令碼放在 Editor 資料夾中。您執行的方法必須定義為靜態的。

自動構建Dmeo

BuildTool.cs

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.IO;
  5 using UnityEngine;
  6 using UnityEditor;
  7 using System.Linq;
  8 using UnityEditor.Build.Reporting;
  9 
 10 public class BuildTool
 11 {
 12     [MenuItem("Build/BuildAndroidWithParameters")]
 13     public static void BuildAndroidWithParameters()
 14     {
 15         CreateBuildAndroid(true);
 16     }
 17 
 18     static void CreateBuildAndroid(bool useIL2CPP, bool development = false)
 19     {
 20         if(EditorUserBuildSettings.activeBuildTarget != BuildTarget.Android)
 21         {
 22             EditorUtility.DisplayDialog("切換到目標平臺", "請切換到安卓平臺,再建立Build", "知道啦");
 23         }
 24 
 25         Debug.Log("Android build started.(" + (useIL2CPP ? "IL2CPP" : "Mono") + ")");
 26 
 27         var target = BuildTarget.Android;
 28         var buildName = GetBuildName();
 29         var buildPath = GetBuildPath(target, buildName);
 30         string executableName = Application.productName + "_proj.android";
 31 
 32         CreateDirectory(buildPath, false);
 33 
 34         var res = BuildGame(buildPath, executableName, target, BuildOptions.CompressWithLz4HC | BuildOptions.AcceptExternalModificationsToPlayer, buildName, useIL2CPP, development);
 35         if (!res)
 36         {
 37             throw new Exception("BuildPipeline.BuildPlayer failed");
 38         }
 39 
 40         if (res.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded)
 41         {
 42             throw new Exception("BuildPipiline.BuildPlayer failed: " + res.ToString());
 43         }
 44 
 45         Debug.Log("Android build completed...");
 46     }
 47 
 48     static string GetBuildName()
 49     {
 50         return "build";
 51     }
 52 
 53     static string GetBuildPath(BuildTarget target, string buildName)
 54     {
 55         return "Build/" + target.ToString() + "/" + GetLongBuildName(target, buildName);
 56     }
 57 
 58     static string GetLongBuildName(BuildTarget target, string buildName)
 59     {
 60         return Application.productName + "_" + target.ToString() + "_" + buildName;
 61     }
 62 
 63     public static void CreateDirectory(string path, bool forceEmpty = false)
 64     {
 65         if (forceEmpty)
 66         {
 67             ClearDirectory(path);
 68         }
 69 
 70         if (!Directory.Exists(path))
 71         {
 72             Directory.CreateDirectory(path);
 73         }
 74     }
 75 
 76     public static void ClearDirectory(string path)
 77     {
 78         if (Directory.Exists(path))
 79         {
 80             Directory.Delete(path);
 81         }
 82     }
 83 
 84     public static BuildReport BuildGame(string buildPath, string exeName, BuildTarget target, BuildOptions opts, string buildId, bool il2cpp, bool development = false)
 85     {
 86         if (development)
 87         {
 88             opts = opts | BuildOptions.Development | BuildOptions.ConnectWithProfiler;
 89         }
 90 
 91         var levels = new string[]
 92         {
 93             "Assets/Tetris Template/Scenes/GamePlay.unity"
 94         };
 95 
 96         BuildTargetGroup group = BuildTargetGroup.Standalone;
 97 
 98         if (!Enum.TryParse(target.ToString(), out group))
 99         {
100             Debug.LogWarning("Building Warning : Unknow Build Target!!!!!!!");
101         }
102 
103         string projectPath = buildPath + "/" + exeName;
104         if (target == BuildTarget.Android || target == BuildTarget.iOS)
105         {
106             projectPath = buildPath + "/../" + exeName;
107         }
108 
109         Debug.Log("Building: " + buildPath);
110         Directory.CreateDirectory(buildPath);
111 
112         string fullBuildPath = Directory.GetCurrentDirectory() + "/" + buildPath;
113         var monoDirs = Directory.GetDirectories(fullBuildPath).Where(s => s.Contains("MonoBleedingEdge"));
114         var il2cppDirs = Directory.GetDirectories(fullBuildPath).Where(s => s.Contains("BackUpThisFolder_ButDontShipItWithYourGame"));
115         var clearFolder = (il2cpp && monoDirs.Count() > 0) || (!il2cpp && il2cppDirs.Count() > 0);
116         if (clearFolder)
117         {
118             Debug.Log("deleting old folders ..");
119             foreach (var file in Directory.GetFiles(fullBuildPath))
120             {
121                 File.Delete(file);
122             }
123 
124             foreach (var dir in monoDirs)
125             {
126                 Directory.Delete(dir, true);
127             }
128 
129             foreach (var dir in il2cppDirs)
130             {
131                 Directory.Delete(dir, true);
132             }
133 
134             foreach (var dir in Directory.GetDirectories(fullBuildPath).Where(s => s.EndsWith("_Data")))
135             {
136                 Directory.Delete(dir, true);
137             }
138         }
139 
140         if (il2cpp)
141         {
142             UnityEditor.PlayerSettings.SetScriptingBackend(group, ScriptingImplementation.IL2CPP);
143             UnityEditor.PlayerSettings.SetIl2CppCompilerConfiguration(group, Il2CppCompilerConfiguration.Release);
144             if (target == BuildTarget.Android)
145             {
146                 PlayerSettings.Android.targetArchitectures = AndroidArchitecture.X86 | AndroidArchitecture.ARMv7 | AndroidArchitecture.ARM64;
147             }
148         }
149         else
150         {
151             UnityEditor.PlayerSettings.SetScriptingBackend(group, ScriptingImplementation.Mono2x);
152         }
153 
154         Debug.Log("Done.");
155 
156         Environment.SetEnvironmentVariable("BUILD_ID", buildId, EnvironmentVariableTarget.Process);
157         var result = BuildPipeline.BuildPlayer(levels, projectPath, target, opts);
158         Environment.SetEnvironmentVariable("BUILD_ID", "", EnvironmentVariableTarget.Process);
159 
160         var stepCount = result.steps.Length;
161         Debug.Log("Steps: " + stepCount);
162         for (int i = 0; i < stepCount; i++)
163         {
164             var step = result.steps[i];
165             Debug.Log("--" + (i + 1) + "/" + stepCount + " " + step.name + " " + step.duration.Seconds + "s--");
166             foreach (var msg in step.messages)
167             {
168                 Debug.Log(msg.content);
169             }
170         }
171 
172         return result;
173     }
174 }
View Code