/// <summary> /// Checks if the <see cref="IBuildInfo"/> has any configuration symbols (i.e. debug, release, or master). /// </summary> /// <param name="buildInfo"></param> /// <returns>True, if the <see cref="IBuildInfo.BuildSymbols"/> contains debug, release, or master.</returns> public static bool HasConfigurationSymbol(this IBuildInfo buildInfo) { return(buildInfo.HasAnySymbols( UnityPlayerBuildTools.BuildSymbolDebug, UnityPlayerBuildTools.BuildSymbolRelease, UnityPlayerBuildTools.BuildSymbolMaster)); }
/// <summary> /// Starts the build process /// </summary> /// <param name="buildInfo"></param> /// <returns>The <see href="https://docs.unity3d.com/ScriptReference/Build.Reporting.BuildReport.html">BuildReport</see> from Unity's <see href="https://docs.unity3d.com/ScriptReference/BuildPipeline.html">BuildPipeline</see></returns> public static BuildReport BuildUnityPlayer(IBuildInfo buildInfo) { EditorUtility.DisplayProgressBar("Build Pipeline", "Gathering Build Data...", 0.25f); // Call the pre-build action, if any buildInfo.PreBuildAction?.Invoke(buildInfo); BuildTargetGroup buildTargetGroup = buildInfo.BuildTarget.GetGroup(); string playerBuildSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); if (!string.IsNullOrEmpty(playerBuildSymbols)) { if (buildInfo.HasConfigurationSymbol()) { buildInfo.AppendWithoutConfigurationSymbols(playerBuildSymbols); } else { buildInfo.AppendSymbols(playerBuildSymbols.Split(';')); } } if (!string.IsNullOrEmpty(buildInfo.BuildSymbols)) { PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, buildInfo.BuildSymbols); } if ((buildInfo.BuildOptions & BuildOptions.Development) == BuildOptions.Development && !buildInfo.HasConfigurationSymbol()) { buildInfo.AppendSymbols(BuildSymbolDebug); } if (buildInfo.HasAnySymbols(BuildSymbolDebug)) { buildInfo.BuildOptions |= BuildOptions.Development | BuildOptions.AllowDebugging; } if (buildInfo.HasAnySymbols(BuildSymbolRelease)) { // Unity automatically adds the DEBUG symbol if the BuildOptions.Development flag is // specified. In order to have debug symbols and the RELEASE symbols we have to // inject the symbol Unity relies on to enable the /debug+ flag of csc.exe which is "DEVELOPMENT_BUILD" buildInfo.AppendSymbols("DEVELOPMENT_BUILD"); } var oldColorSpace = PlayerSettings.colorSpace; if (buildInfo.ColorSpace.HasValue) { PlayerSettings.colorSpace = buildInfo.ColorSpace.Value; } if (buildInfo.ScriptingBackend.HasValue) { PlayerSettings.SetScriptingBackend(buildTargetGroup, buildInfo.ScriptingBackend.Value); #if !UNITY_2019_1_OR_NEWER // When building the .NET backend, also build the C# projects, as the // intent of this build process is to prove that it's possible build // a solution where the local dev loop can be accomplished in the // generated C# projects. if (buildInfo.ScriptingBackend == ScriptingImplementation.WinRTDotNET) { EditorUserBuildSettings.wsaGenerateReferenceProjects = true; } #endif } BuildTarget oldBuildTarget = EditorUserBuildSettings.activeBuildTarget; BuildTargetGroup oldBuildTargetGroup = oldBuildTarget.GetGroup(); if (EditorUserBuildSettings.activeBuildTarget != buildInfo.BuildTarget) { EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, buildInfo.BuildTarget); } switch (buildInfo.BuildTarget) { case BuildTarget.Android: buildInfo.OutputDirectory = $"{buildInfo.OutputDirectory}/{PlayerSettings.productName}.apk"; break; case BuildTarget.StandaloneWindows: case BuildTarget.StandaloneWindows64: buildInfo.OutputDirectory = $"{buildInfo.OutputDirectory}/{PlayerSettings.productName}.exe"; break; } BuildReport buildReport = default; try { buildReport = BuildPipeline.BuildPlayer( buildInfo.Scenes.ToArray(), buildInfo.OutputDirectory, buildInfo.BuildTarget, buildInfo.BuildOptions); } catch (Exception e) { Debug.LogError($"{e.Message}\n{e.StackTrace}"); } PlayerSettings.colorSpace = oldColorSpace; if (EditorUserBuildSettings.activeBuildTarget != oldBuildTarget) { EditorUserBuildSettings.SwitchActiveBuildTarget(oldBuildTargetGroup, oldBuildTarget); } // Call the post-build action, if any buildInfo.PostBuildAction?.Invoke(buildInfo, buildReport); return(buildReport); }
/// <summary> /// Starts the build process /// </summary> /// <param name="buildInfo"></param> /// <returns>The <see cref="BuildReport"/> from Unity's <see cref="BuildPipeline"/></returns> public static BuildReport BuildUnityPlayer(IBuildInfo buildInfo) { EditorUtility.DisplayProgressBar("Build Pipeline", "Gathering Build Data...", 0.25f); // Call the pre-build action, if any buildInfo.PreBuildAction?.Invoke(buildInfo); var buildTargetGroup = buildInfo.BuildTarget.GetGroup(); var playerBuildSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); if (!string.IsNullOrEmpty(playerBuildSymbols)) { if (buildInfo.HasConfigurationSymbol()) { buildInfo.AppendWithoutConfigurationSymbols(playerBuildSymbols); } else { buildInfo.AppendSymbols(playerBuildSymbols.Split(';')); } } if (!string.IsNullOrEmpty(buildInfo.BuildSymbols)) { PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, buildInfo.BuildSymbols); } if ((buildInfo.BuildOptions & BuildOptions.Development) == BuildOptions.Development && !buildInfo.HasConfigurationSymbol()) { buildInfo.AppendSymbols(BuildSymbolDebug); } if (buildInfo.HasAnySymbols(BuildSymbolDebug)) { buildInfo.BuildOptions |= BuildOptions.Development | BuildOptions.AllowDebugging; } if (buildInfo.HasAnySymbols(BuildSymbolRelease)) { // Unity automatically adds the DEBUG symbol if the BuildOptions.Development flag is // specified. In order to have debug symbols and the RELEASE symbols we have to // inject the symbol Unity relies on to enable the /debug+ flag of csc.exe which is "DEVELOPMENT_BUILD" buildInfo.AppendSymbols("DEVELOPMENT_BUILD"); } var oldColorSpace = PlayerSettings.colorSpace; if (buildInfo.ColorSpace.HasValue) { PlayerSettings.colorSpace = buildInfo.ColorSpace.Value; } var oldBuildTarget = EditorUserBuildSettings.activeBuildTarget; var oldBuildTargetGroup = oldBuildTarget.GetGroup(); if (EditorUserBuildSettings.activeBuildTarget != buildInfo.BuildTarget) { EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, buildInfo.BuildTarget); } switch (buildInfo.BuildTarget) { case BuildTarget.Lumin: buildInfo.OutputDirectory = $"{buildInfo.OutputDirectory}/{PlayerSettings.productName}.mpk"; break; case BuildTarget.Android: buildInfo.OutputDirectory = $"{buildInfo.OutputDirectory}/{PlayerSettings.productName}.apk"; break; case BuildTarget.StandaloneWindows: case BuildTarget.StandaloneWindows64: buildInfo.OutputDirectory = $"{buildInfo.OutputDirectory}/{PlayerSettings.productName}.exe"; break; } BuildReport buildReport = default; if (Application.isBatchMode) { foreach (var scene in buildInfo.Scenes) { Debug.Log($"BuildScene->{scene.path}"); } } try { buildReport = BuildPipeline.BuildPlayer( buildInfo.Scenes.ToArray(), buildInfo.OutputDirectory, buildInfo.BuildTarget, buildInfo.BuildOptions); } catch (Exception e) { Debug.LogError($"{e.Message}\n{e.StackTrace}"); } PlayerSettings.colorSpace = oldColorSpace; if (EditorUserBuildSettings.activeBuildTarget != oldBuildTarget) { EditorUserBuildSettings.SwitchActiveBuildTarget(oldBuildTargetGroup, oldBuildTarget); } // Call the post-build action, if any buildInfo.PostBuildAction?.Invoke(buildInfo, buildReport); return(buildReport); }