Skip to content

Instantly share code, notes, and snippets.

@v01pe
Created August 4, 2021 10:30
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save v01pe/2682af25e029aa517d3b3431231bd7f4 to your computer and use it in GitHub Desktop.
Save v01pe/2682af25e029aa517d3b3431231bd7f4 to your computer and use it in GitHub Desktop.
Build pre- and post-processing. Workaround for missing build canceled delegate.
using System;
using UnityEditor;
using UnityEditor.Build;
using UnityEngine;
using Object = UnityEngine.Object;
[InitializeOnLoad]
public class BuildHandler : MonoBehaviour
{
/// <summary>
/// This is invoked, before any Unity build steps are taken,
/// this means also before e.g. <see cref="IPreprocessBuildWithReport"/>.<para/>
/// In the case of an <see cref="Exception"/>, invocation is interrupted,
/// the build is not even started. but <see cref="OnBuildCleanup"/>
/// is still invoked on every delegate.
/// </summary>
public static event Action OnBuildStarted;
/// <summary>
/// Finally, this is invoked after a build completed <b>or</b> failed.
/// This can be used to clean up any build artifacts. If the build failed,
/// <see cref="IPostprocessBuildWithReport"/> isn't called, so this event
/// can be used as a workaround. <see cref="Exception"/>s are caught per invocation, so
/// it's guaranteed, that every delegate is invoked.
/// </summary>
public static event Action OnBuildCleanup;
static BuildHandler()
{
BuildPlayerWindow.RegisterBuildPlayerHandler(Build);
}
private static void Build(BuildPlayerOptions buildOptions)
{
try
{
BuildStarted();
//now start Unity's default building procedure
BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(buildOptions);
}
catch (BuildPlayerWindow.BuildMethodException) { } //logged internally
catch (Exception ex)
{
Exception log = ex.InnerException == null ? ex : ex.InnerException;
Debug.LogException(log);
Debug.LogErrorFormat("{0} in BuildHandler: '{1}'", log.GetType().Name, ex.Message);
}
finally
{
BuildCleanup();
}
}
private static void BuildStarted()
{
try
{
OnBuildStarted?.Invoke();
}
catch (Exception ex)
{
throw new Exception("OnBuildStarted failed", ex);
}
}
private static void BuildCleanup()
{
if (OnBuildCleanup != null)
{
foreach (Action cleanupBuild in OnBuildCleanup.GetInvocationList())
{
try
{
cleanupBuild.Invoke();
}
catch (Exception ex)
{
Object context = cleanupBuild.Target as Object;
Debug.LogException(ex, context);
Debug.LogWarning("Caught exception while BuildHandler.OnBuildCleanup... Continuing");
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment