关注

如何通过命令行或自动构建系统支持不同的配置来构建特定的玩家?

问题

  • 我需要为项目中特定场景支持不同的构建设置(例如构建禁用硬件统计信息标志或删除自定义分析事件),并通过命令行或自动构建系统调用这些配置(例如Jenkins)。
  • 我需要支持在iOS、Android、iOSTest、AndroidTest、WebGL或其他平台上自动构建我的游戏,并通过命令行调用它们与构建系统集成。

原因

Unity构建不同的玩家,但是为他们使用相似的全局配置。例如,如果项目使用PlayerSettings.SetScriptingDefineSymbolsForGroup 实现Custom Defines,您可能禁止这个功能,以便进行特定的测试,但是在生产构建的时候又需要激活它。Unity本身并不支持这个功能,所以您务必创建不同的构建脚本,以支持自定义设置。

解决方案

您可以借助Unity Cloud Build云构建实现该功能,它支持对不同场景下多种构建设置。欲了解更多信息,请参考Unity Cloud Build documentation.

您也可以创建某方法实现构建验证、更改设置和创建多种玩家。这些方法必须位于编辑器文件夹中的代码文件中,例如Assets/Editor/Builders/AndroidBuilder.cs。这个类不需要扩展任何Unity类 – 唯一的要求是使用静态函数。

例如,您想要Android、AndroidTest和iOS的三种构建,并使用控制命令行(或自动构建系统)去自动化地创建它们。如下所示,您可以建立两个脚本:: AndoidBuilder.cs (Assets/Editor/Builders/AndroidBuilder.cs) 和 iOSBuilder.cs (Assets/Editor/Builders/iOSBuilder.cs):

 

AndroidBuilder.cs:

using UnityEditor;

class AndroidBuilder
{
    static void ProductionBuild()
    {
        // ... your code here, validations, flag changes, etc.

        // Build the player.\
        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
        buildPlayerOptions.scenes = new[] { "Assets/Scene1.unity", "Assets/Scene2.unity" };
        buildPlayerOptions.locationPathName = "AndroidProdBuild";
        buildPlayerOptions.target = BuildTarget.Android;
        buildPlayerOptions.options = BuildOptions.None;
        BuildPipeline.BuildPlayer(buildPlayerOptions);
    }

    static void TestBuild ()
    {
        // ... your code here, validations, flag changes, etc.

        // Build the player.\
        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
        buildPlayerOptions.scenes = new[] { "Assets/SceneTest1.unity", "Assets/SceneTest2.unity" };
        buildPlayerOptions.locationPathName = "AndroidTestBuild";
        buildPlayerOptions.target = BuildTarget.Android;
        buildPlayerOptions.options = BuildOptions.None;
        BuildPipeline.BuildPlayer(buildPlayerOptions);
    }
}

iOSBuilder.cs:

using UnityEditor;

class iOSBuilder
{

    static void ProductionBuild()
    {
        // ... your code here, validations, flag changes, etc.

        // Build the player.\
        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
        buildPlayerOptions.scenes = new[] { "Assets/Scene1.unity", "Assets/Scene2.unity" };
        buildPlayerOptions.locationPathName = "iOSProdBuild";
        buildPlayerOptions.target = BuildTarget.iOS;
        buildPlayerOptions.options = BuildOptions.None;
        BuildPipeline.BuildPlayer(buildPlayerOptions);
    }
}

接下来,您可以使用下面的代码调用每个构建函数:

  • /Path/To/Unity -quit -batchmode -executeMethod AndroidBuilder.ProductionBuild
  • /Path/To/Unity -quit -batchmode -executeMethod AndroidBuilder.TestBuild
  • /Path/To/Unity -quit -batchmode -executeMethod iOSBuilder.ProductionBuild

另一个方法是仅有一个构建脚本,通过命令行使用参数来选择应该建立哪个玩家。下面是一个例子:

 

Builder.cs:

using UnityEditor;
using System;

class Builder
{
    static void iOSProductionBuild()
    {
        // ... your code here, validations, flag changes, etc.

        // Build the player.\
        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
        buildPlayerOptions.scenes = new[] { "Assets/Scene1.unity", "Assets/Scene2.unity" };
        buildPlayerOptions.locationPathName = "iOSProdBuild";
        buildPlayerOptions.target = BuildTarget.iOS;
        buildPlayerOptions.options = BuildOptions.None;
        BuildPipeline.BuildPlayer(buildPlayerOptions);
    }

    static void AndroidProductionBuild()
    {
        // ... your code here, validations, flag changes, etc.

        // Build the player.\
        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
        buildPlayerOptions.scenes = new[] { "Assets/Scene1.unity", "Assets/Scene2.unity" };
        buildPlayerOptions.locationPathName = "AndroidProdBuild";
        buildPlayerOptions.target = BuildTarget.Android;
        buildPlayerOptions.options = BuildOptions.None;
        BuildPipeline.BuildPlayer(buildPlayerOptions);
    }

    static void AndroidTestBuild()
    {
        // ... your code here, validations, flag changes, etc.

        // Build the player.\
        BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
        buildPlayerOptions.scenes = new[] { "Assets/SceneTest1.unity", "Assets/SceneTest2.unity" };
        buildPlayerOptions.locationPathName = "AndroidTestBuild";
        buildPlayerOptions.target = BuildTarget.Android;
        buildPlayerOptions.options = BuildOptions.None;
        BuildPipeline.BuildPlayer(buildPlayerOptions);
    }


    static void Build ()
    {
        string[] arguments = Environment.GetCommandLineArgs();
        switch ( arguments[1] )
        {
            case "Android":
                AndroidProductionBuild();
                break;
            case "AndroidTest":
                AndroidTestBuild();
                break;
            case "iOS":
                iOSProductionBuild();
                break;
            default:
                AndroidProductionBuild();
                break;
        }
    }
}

您可以使用下面的代码调用构建函数:

  • /Path/To/Unity -quit -batchmode -executeMethod Builder.Build Android
  • /Path/To/Unity -quit -batchmode -executeMethod Builder.Build AndroidTest
  • /Path/To/Unity -quit -batchmode -executeMethod Builder.Build iOS

您可以通过使用其他参数(例如-target=Android|iOS -env=prod|dev)或自定义参数来扩展此方法。

您可以将这些方法和自动构建系统相结合,从而自动创建不同需求下的不同玩家,避免构建时的人为错误。

用这种方法,您可以实现下列自定义方法:

  • 不同场景的开发构建。
  • 使用PlayerSettings.SetScriptingDefineSymbolsForGroup自定义脚本#define指令。
  • 包括/剔除插件。
  • 包括/剔除特定场景。
  • 编辑任何MyProject/ProjectSettings/*.asset下的资源文件(例如AudioManager.asset, GraphicsSettings.asset和ProjectSettings.asset)
  • 使用C#脚本更新资源。
  • 根据项目需求开启或关闭自定义插件(例如通过平台、渲染API或任何其他特定功能)。
  • 在必要时,使用任何C#脚本。

更多信息

更多信息请参考以下文档:

 

这篇文章有帮助吗?
0 人中有 0 人觉得有帮助
还有其它问题?提交请求

0 评论

登录写评论。