自动任务构建
通常可以在桌面双击 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 }