Unity可执行命令的路径

在 macOS 上,在终端中输入以下命令来启动 Unity:

/Applications/Unity/Hub/Editor/<version>/Unity.app/Contents/MacOS/Unity -projectPath <project path>

On Linux, type the following into the Terminal to launch Unity:

/Applications/Unity/Hub/Editor/<version>/Unity.app/Contents/Linux/Unity -projectPath <project path>

在 Windows 上,在命令提示符下输入以下命令来启动 Unity:

"C:\Program Files\Unity\Hub\Editor\<version>\Editor\Unity.exe" -projectPath "<project path>"

When you launch Unity like this, it receives commands and information on startup, which can be useful for test suites, automated builds and other production tasks.

Unity命令参数

-batchmode
//在 batch mode 下執行 Unity
//需要注意,Unity 只允許同時間存在一個執行程序
 
-quit
//在命令行結束執行時,關閉 Unity Editor
//需要注意使用這個功能,會導致無法在 Unity Editor 中查看錯誤訊息
 
-projectPath <pathname>
//Unity 專案路徑
 
-logFile <pathname>
//建置日誌路徑
 
-executeMethod <ClassName.MethodName>
//開啟 Unity 時,執行類別中的靜態方法
//可利用於 CI、Unit Tests、版本建置、資料處理...等。
//要注意類別腳本需要放置在 Editor 資料夾中

使用示例

$unity -projectPath xxxxx 从命令行打开Unity

Unity命令可以跟Unity的菜单配合使用

using UnityEditor;
using UnityEngine;
using System;
using System.IO;
using System.Collections.Generic;
 
public class BuildTool
{
    [MenuItem("BuildTool/Build")]
    private static void Build()
    {
        CustomizedCommandLine();
 
        string destinationPath = Path.Combine(_destinationPath, PlayerSettings.productName);
        destinationPath += GetExtension();
 
        BuildPipeline.BuildPlayer(EditorBuildSettings.scenes, destinationPath, EditorUserBuildSettings.activeBuildTarget, BuildOptions.None);
    }
 
 
    private static string _destinationPath;
    private static void CustomizedCommandLine()
    {
        Dictionary<string, Action<string>> cmdActions = new Dictionary<string, Action<string>>
        {
            {
                "-destinationPath", delegate(string argument)
                {
                    _destinationPath = argument;
                }
            }
        };
 
        Action<string> actionCache;
        string[] cmdArguments = Environment.GetCommandLineArgs();
 
        for (int count = 0; count < cmdArguments.Length; count++)
        {
            if (cmdActions.ContainsKey(cmdArguments[count]))
            {
                actionCache = cmdActions[cmdArguments[count]];
                actionCache(cmdArguments[count + 1]);
            }
        }
 
        if (string.IsNullOrEmpty(_destinationPath))
        {
            _destinationPath = Path.GetDirectoryName(Application.dataPath);
        }
    }
 
 
    private static string GetExtension()
    {
        string extension = "";
 
        switch (EditorUserBuildSettings.activeBuildTarget)
        {
            case BuildTarget.StandaloneOSXIntel:
            case BuildTarget.StandaloneOSXIntel64:
            case BuildTarget.StandaloneOSXUniversal:
                extension = ".app";
                break;
            case BuildTarget.StandaloneWindows:
            case BuildTarget.StandaloneWindows64:
                extension = ".exe";
                break;
            case BuildTarget.Android:
                extension = ".apk";
                break;
        }
 
        return extension;
    }
}
#!/bin/bash
 
UNITY_PATH=/Applications/Unity/Unity.app/Contents/MacOS/Unity
PROJECT_PATH=/Users/ted/SideProjects/UnityCommandLineBuild
BUILD_LOG_PATH=${PROJECT_PATH}/build.log
DESTINATION_PATH=/Users/ted/Desktop/

$UNITY_PATH -quit -batchmode -projectPath ${PROJECT_PATH} -executeMethod BuildTool.Build -logFile ${BUILD_LOG_PATH} -destinationPath ${DESTINATION_PATH}

调用构建API的最简方式

using UnityEditor;
class MyEditorScript
{
     static void PerformBuild ()
     {
        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
        buildPlayerOptions.scenes = new[] { "Assets/Scene1.unity", "Assets/Scene2.unity" };
        BuildPipeline.BuildPlayer(buildPlayerOptions);
     }
}
/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -projectPath ~/UnityProjects/MyProject -executeMethod MyEditorScript.PerformBuild

除了明确指定场景,也可以使用编辑器中的默认场景。

using UnityEditor;

public class MyEditorScript
{
    public static void PerformBuild()
    {
        BuildPipeline.BuildPlayer(EditorBuildSettings.scenes, "a.apk", EditorUserBuildSettings.activeBuildTarget, BuildOptions.None);
    }
}

技巧

Unity对于一个项目只能打开一次,在Unity打开的情况下,上述编译命令就不可用了。报错一个项目只允许打开一次。

Aborting batchmode due to failure:
Fatal Error! It looks like another Unity instance is running with this project open.

Multiple Unity instances cannot open the same project.


如何解决这个问题呢?
把文件夹复制一份,然后执行上述命令。
注意:使用软链接是不行的,必须使用复制的方式。

获取当前活跃场景

EditorBuildSettingsScene.GetActiveSceneList()

var x=EditorSceneManager.GetActiveScene();

获取XR Settings

  var m=XRGeneralSettings.Instance.Manager;
        m.load
            XRGeneralSettings generalSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(BuildTargetGroup.Android);
            if (generalSettings == null) return false;
                var assignedSettings = generalSettings.AssignedSettings;
            if (assignedSettings == null) return false;
#if UNITY_2021_1_OR_NEWER
            foreach (XRLoader loader in assignedSettings.activeLoaders)
            {
                if (loader is PXR_Loader) return true;
            }
#else
            foreach (XRLoader loader in assignedSettings.loaders)
            {
                if (loader is PXR_Loader) return true;
            }

XR Editor配置 https://docs.unity3d.com/Packages/com.unity.xr.management@4.0/manual/EndUser.html

运行当前场景 BuildPipeline scenes传空即可。

参考资料

https://docs.unity3d.com/Manual/CommandLineArguments.html