Unity的batchmode和.bat实现多平台自动化编译打包游戏

最近一个已上线项目需要开发新的东西,并且它是在多个平台上线的。那么在日常的迭代开发过程中,设计和测试定时的需要一个当前最新的版本来查看游戏目前的一个开发状态,如果他们每个人都跑来找程序手动的打新版本,那么程序一天啥也不干就光给设计和测试打版本了。。。
于是我就写了一个.bat批处理利用Unity的batchmode来实现每天定时打版本。废话不多说,直接上代码。

bat批处理脚本:

@echo off
cd>nul
REM GET THE COMMAND LINE ARGS
SET PLATFORM=%1
REM PLATFORM possible options are: Standalone, Win, Win64, OSXUniversal, Linux64, iOS, Android, WebGL, XboxOne, PS4, WindowsStoreApps, Switch, tvOS.
SET CONFIG=%2
SET OUTPUT=%3
SET PACKAGE=%4
SET BUILDNO=%5

SET UNITY_INSTALL_ROOT_KEY="HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Unity"
SET UNITY_ICON_KEY="DisplayIcon"

FOR /F "skip=2 tokens=1,2*" %%A IN ('REG QUERY "%UNITY_INSTALL_ROOT_KEY%" /v "%UNITY_ICON_KEY%" 2^>nul') DO (
    SET ValueName=%%A
    SET ValueType=%%B
    SET ValueValue=%%C
)
if defined ValueValue (
    ECHO Unity installation detected!  
    ECHO %ValueValue%
) else (
    ECHO "%KEY_NAME%"\"%VALUE_NAME%" not be found.
    EXIT
)

PUSHD %~dp0
SET UNITY=%ValueValue%
SET LOGFILE=%CD%\build_%PLATFORM%_%CONFIG%.log
IF NOT EXIST %OUTPUT% MKDIR %OUTPUT%
ECHO Build Command:
SET BUILDCMD="%UNITY%" -buildTarget "%PLATFORM%" -batchmode -quit -projectPath %CD% -logFile "%LOGFILE%" -executeMethod AutoBuildProcessor.Build 
ECHO %BUILDCMD%
%BUILDCMD% -buildArgs:"platform=%PLATFORM%;config=%CONFIG%;output=%OUTPUT%;ispackage=%PACKAGE%;buildno=%BUILDNO%;scenes=MyScreen1&MyScreen2"
SET SHOWLOG=TYPE %LOGFILE%
%SHOWLOG%

POPD

@echo on
exit %ErrorLevel%

上面.bat批处理脚本完成了:

  1. 读取执行.bat脚本时传入的参数;
  2. 检查当前环境下是否安装有对应版本的Unity;
  3. 创建编译时输出的log文件;
  4. 执行Unity的batchmode下的相关命令;
  5. 最后执行项目工程里类AutoBuildProcessor的static函数Build完成编译打包。

AutoBuildProcessor.cs代码:

public class AutoBuildProcessor
{
	public static void Build()
    {
        string buildPlatform = CommandLineParser.GetCustomArgument("platform");
        string buildConfig = CommandLineParser.GetCustomArgument("config");
        string buildOutput = CommandLineParser.GetCustomArgument("output");
        string buildPackage = CommandLineParser.GetCustomArgument("ispackage");
        string buildno = CommandLineParser.GetCustomArgument("buildno");
        string scenesConfig = CommandLineParser.GetCustomArgument("scenes");

     	UnityEngine.Debug.Log("CustomArgs: buildPlatform=" + buildPlatform + " | buildConfig=" + buildConfig + " | buildOutput=" + buildOutput + " | buildNO=" + buildno + " | isBuildPackage=" + buildPackage);

        string[] scenes = { };
        if (scenesConfig.Length != 0)
        {
            string[] sceneList = scenesConfig.Split('&');
            if (sceneList.Length != 0)
                scenes = new string[sceneList.Length];
            for (int i = 0; i < sceneList.Length; i++)
            {
                UnityEngine.Debug.Log("Build Scene: " + sceneList[i]);
                scenes[i] = string.Format("Assets/Scenes/{0}.unity", sceneList[i]);
            }
        }

        BuildTargetGroup group = BuildTargetGroup.Unknown;
        BuildTarget target = BuildTarget.StandaloneWindows;
        string ScriptingDefineSymbols = "";

        buildPlatform = buildPlatform.ToUpper();
        if (buildPlatform == "WIN32")
        {
            group = BuildTargetGroup.Standalone;
            target = BuildTarget.StandaloneWindows;
            ScriptingDefineSymbols = "MyWin32CustomDefineSymbols1; MyWin32CustomDefineSymbols2";
        }
        else if (buildPlatform == "WIN64")
        {
            group = BuildTargetGroup.Standalone;
            target = BuildTarget.StandaloneWindows64;
            ScriptingDefineSymbols = "MyWin64CustomDefineSymbols1; MyWin64CustomDefineSymbols2";
        }
        else if (buildPlatform == "IOS")
        {
            group = BuildTargetGroup.iOS;
            target = BuildTarget.iOS
            ScriptingDefineSymbols = "MyIOSCustomDefineSymbols1; MyIOSCustomDefineSymbols2";
        }
        else if (buildPlatform == "ANDROID")
        {
            group = BuildTargetGroup.Android;
            target = BuildTarget.Android;
            ScriptingDefineSymbols = "MyAndroidCustomDefineSymbols1; MyAndroidCustomDefineSymbols2";
        }
        //else if ()
        //{
        //  You can add more platforms to build
        //}

        PlayerSettings.SetScriptingDefineSymbolsForGroup(group, ScriptingDefineSymbols);

        //switch platform. NOTE: This method is not available when running the Editor in batch mode.
        //EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Switch, target);

        if (!System.IO.Directory.Exists(buildOutput))
            System.IO.Directory.CreateDirectory(buildOutput);

        EditorUserBuildSettings.explicitNullChecks = true;

        BuildOptions option = BuildOptions.None;
        if (buildConfig.ToUpper() == "DEBUG")
        {
            option = BuildOptions.AllowDebugging | BuildOptions.Development;
        }

        string executablePrefix = "MyGame";
        string executableSuffix = ".exe"; //Need to change others based on different platforms
        string outputPath = buildOutput + "/" + executablePrefix + executableSuffix;

        BuildPipeline.BuildAssetBundles("Assets", BuildAssetBundleOptions.ForceRebuildAssetBundle | BuildAssetBundleOptions.DeterministicAssetBundle, target);
        string buildResult = BuildPipeline.BuildPlayer(scenes, outputPath, target, option).ToString();
    }
}

public class CommandLineParser
{
    private const string kCustomArgPrefix = "-buildArgs:";
    private const char kCustomArgSeparator = ';';
    private static char[] kCustomArgStartEndMark = { '\"' };
    private enum ECustomArgumentType { CustomArgumentKey, CustomArgumentValue, CustomArgumentSize };
    private static Dictionary<string, string> sCustomArgsDict = null;

    public static Dictionary<string, string> GetCustomArguments()
    {
        Dictionary<string, string> customArgsDict = new Dictionary<string, string>();
        string[] commandLineArgs = Environment.GetCommandLineArgs();
        string[] customArgs;
        string[] customArgBuffer;
        string customArgsStr = "";

        try
        {
            customArgsStr = commandLineArgs.Where(row => row.Contains(kCustomArgPrefix)).Single();
        }
        catch (Exception e)
        {
            UnityEngine.Debug.LogError("GetCustomArguments: Can't retrieve any custom arguments in the command line [" + commandLineArgs + "]. Exception: " + e);
            return customArgsDict;
        }

        customArgsStr = customArgsStr.Replace(kCustomArgPrefix, "");
        customArgsStr = customArgsStr.Trim(kCustomArgStartEndMark);
        customArgs = customArgsStr.Split(kCustomArgSeparator);
        foreach (string customArg in customArgs)
        {
            customArgBuffer = customArg.Split('=');
            if (customArgBuffer.Length == (int)ECustomArgumentType.CustomArgumentSize)
            {
                customArgsDict.Add(customArgBuffer[(int)ECustomArgumentType.CustomArgumentKey], customArgBuffer[(int)ECustomArgumentType.CustomArgumentValue]);

            }
            else
            {
                UnityEngine.Debug.LogWarning("GetCustomArguments: The custom argument [" + customArg + "] seem to be malformed.");
            }
        }

        return customArgsDict;
    }

    public static string GetCustomArgument(string _argumentName, string fallback = "")
    {
        if (sCustomArgsDict == null)
            sCustomArgsDict = GetCustomArguments();

        if (sCustomArgsDict.ContainsKey(_argumentName))
        {
            return sCustomArgsDict[_argumentName];
        }
        else
        {
            UnityEngine.Debug.LogWarning("GetCustomArgument: Can't retrieve any custom argument named [" + _argumentName + "] in the command line [" + Environment.GetCommandLineArgs() + "].");
            return fallback;
        }
    }
}

最后将.bat批处理脚本放到Unity工程根目录下执行它就可以完成自动编译打包(当然,是在你的游戏工程没有编译错误的前提下!)。
那么,又怎么让它每天定时的执行呢?在Windows环境下可以使用它自带的[任务计划程序]应用。
在这里插入图片描述
在这里插入图片描述
这个应用的具体使用方法可以自行网上搜索。
如果是Mac环境下的话可以使用Shell脚本和Jenkins来达到相同的目的。这个等我以后有时间了也去上手试一下再来分享。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值