命令列構建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命令列引數
如上所述,在啟動編輯器和構建遊戲時,也可以選擇性地使用其他命令和資訊。使用以下命令列引數並可達到這一目的:
官方文件引數說明:
-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