Skip to content

Instantly share code, notes, and snippets.

@daemon3000
Created July 9, 2018 10:03
Show Gist options
  • Save daemon3000/7b31864cc843bbc3ba9a008231a5fd99 to your computer and use it in GitHub Desktop.
Save daemon3000/7b31864cc843bbc3ba9a008231a5fd99 to your computer and use it in GitHub Desktop.
#region [Copyright (c) 2018 Cristian Alexandru Geambasu]
// Distributed under the terms of an MIT-style license:
//
// The MIT License
//
// Copyright (c) 2018 Cristian Alexandru Geambasu
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#endregion
// REQUIRES Json.Net
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using UnityBuildOptions = UnityEditor.BuildOptions;
using UnityBuildPlayerOptions = UnityEditor.BuildPlayerOptions;
using UnityEditor.Build.Reporting;
namespace LuminosityEditor.Tools
{
public class BuildOptions
{
public string BuildFolder;
public string ExecutableName;
public string[] Scenes;
public BuildPlayerOptions[] Builds;
public BuildOptions()
{
BuildFolder = null;
ExecutableName = null;
Scenes = new string[0];
Builds = new BuildPlayerOptions[0];
}
}
public struct BuildPlayerOptions
{
public string Name;
public string MenuPath;
public string PlatformID;
public string Extension;
public string DebugScriptingSymbols;
public string ReleaseScriptingSymbols;
public BuildTarget BuildTarget;
public BuildTargetGroup BuildTargetGroup;
}
public enum BuildType
{
Debug, Release
}
public static class BuildToolbox
{
private static BuildOptions buildOptions;
public static BuildOptions BuildOptions
{
get { return buildOptions; }
}
[InitializeOnLoadMethod]
public static void OnLoadBuildOptions()
{
TextAsset asset = Resources.Load<TextAsset>("build_options");
try
{
if(asset != null)
{
buildOptions = JsonConvert.DeserializeObject<BuildOptions>(asset.text);
}
else
{
buildOptions = new BuildOptions();
}
}
catch(System.Exception ex)
{
Debug.LogException(ex);
buildOptions = new BuildOptions();
}
}
public static void OnShowBuildDropdown(Vector2 position)
{
Rect rect = new Rect(position, Vector2.zero);
GenericMenu menu = new GenericMenu();
string[] buildNames = (from bo in BuildOptions.Builds select bo.MenuPath).ToArray();
for(int i = 0; i < buildNames.Length; i++)
{
menu.AddItem(new GUIContent(buildNames[i] + "/Debug"), false, arg => { Build(BuildType.Debug, (int)arg); }, i);
menu.AddItem(new GUIContent(buildNames[i] + "/Release"), false, arg => { Build(BuildType.Release, (int)arg); }, i);
}
menu.DropDown(rect);
}
public static void OpenBuildFolder()
{
string buildFolder = string.Concat(EditorToolbox.ProjectPath, "/", buildOptions.BuildFolder);
EditorToolbox.OpenFolderInExplorer(buildFolder);
}
public static void Build(BuildType buildType, int playerOptionsIndex)
{
BuildPlayerOptions playerOptions = buildOptions.Builds[playerOptionsIndex];
string originalScriptSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(playerOptions.BuildTargetGroup);
string scriptSymbols = buildType == BuildType.Debug ? playerOptions.DebugScriptingSymbols : playerOptions.ReleaseScriptingSymbols;
EditorUtility.DisplayProgressBar("Hold On", "Starting build process...", 0.0f);
if(!CleanBuildPath(playerOptions))
{
EditorUtility.ClearProgressBar();
EditorUtility.DisplayDialog("Error", "Failed to delete old build folder. Make sure none of the files are open in another program.", "OK");
return;
}
PlayerSettings.SetScriptingDefineSymbolsForGroup(playerOptions.BuildTargetGroup, scriptSymbols);
EditorUtility.ClearProgressBar();
BuildReport buildReport = BuildPipeline.BuildPlayer(GenerateUnityPlayerOptions(buildType, buildOptions.Scenes, playerOptions));
if(buildReport.summary.result == BuildResult.Succeeded)
{
OpenBuildFolder();
}
else
{
Debug.LogError("Failed to build game!");
}
PlayerSettings.SetScriptingDefineSymbolsForGroup(playerOptions.BuildTargetGroup, originalScriptSymbols);
}
private static string GenerateBuildPath(BuildPlayerOptions playerOptions)
{
if(!string.IsNullOrEmpty(playerOptions.Extension))
{
return string.Concat(EditorToolbox.ProjectPath,
"/", buildOptions.BuildFolder,
"/", buildOptions.ExecutableName, "_", playerOptions.PlatformID,
"/", buildOptions.ExecutableName, playerOptions.Extension);
}
else
{
return string.Concat(EditorToolbox.ProjectPath,
"/", buildOptions.BuildFolder,
"/", buildOptions.ExecutableName, "_", playerOptions.PlatformID);
}
}
private static UnityBuildPlayerOptions GenerateUnityPlayerOptions(BuildType buildType, string[] scenes, BuildPlayerOptions playerOptions)
{
return new UnityBuildPlayerOptions
{
scenes = scenes,
locationPathName = GenerateBuildPath(playerOptions),
targetGroup = playerOptions.BuildTargetGroup,
target = playerOptions.BuildTarget,
options = (buildType == BuildType.Debug) ? UnityBuildOptions.Development : UnityBuildOptions.None
};
}
private static bool CleanBuildPath(BuildPlayerOptions playerOptions)
{
try
{
string buildPath = GenerateBuildPath(playerOptions);
if(!string.IsNullOrEmpty(playerOptions.Extension))
{
string folder = Path.GetDirectoryName(buildPath);
if(Directory.Exists(folder))
Directory.Delete(folder, true);
Directory.CreateDirectory(folder);
}
else
{
if(Directory.Exists(buildPath))
Directory.Delete(buildPath, true);
Directory.CreateDirectory(buildPath);
}
return true;
}
catch(System.Exception ex)
{
Debug.LogException(ex);
return false;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment