命令行构建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

 

posted @ 2021-11-22 15:38  Ring_1992  阅读(498)  评论(0编辑  收藏  举报