Skip to content

Instantly share code, notes, and snippets.

@kalineh
Created March 13, 2019 23:43
Show Gist options
  • Save kalineh/cb492a5673c09030a78f3a6aafe84f71 to your computer and use it in GitHub Desktop.
Save kalineh/cb492a5673c09030a78f3a6aafe84f71 to your computer and use it in GitHub Desktop.
RebuildRunHelper.cs
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
public static class RebuildRunHelper
{
public enum RebuildStage
{
None,
Requested,
WaitStopPlaying,
WaitAssetRefresh,
WaitPlayStart,
WaitSceneLoad,
};
static RebuildRunHelper()
{
EditorApplication.update -= OnUpdate;
EditorApplication.update += OnUpdate;
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
}
[UnityEditor.Callbacks.DidReloadScripts]
private static void OnReloadScripts()
{
EditorApplication.update -= OnUpdate;
EditorApplication.update += OnUpdate;
}
private static void OnPlayModeStateChanged(PlayModeStateChange state)
{
//Debug.LogFormat("PlayModeState: {0} (stage: {1})", state, GetStage());
//Debug.LogFormat("> updating: {0}", EditorApplication.isUpdating);
//Debug.LogFormat("> compiling: {0}", EditorApplication.isCompiling);
//Debug.LogFormat("> paused:: {0}", EditorApplication.isPaused);
var stage = GetStage();
if (stage == RebuildStage.WaitPlayStart)
{
if (state == PlayModeStateChange.EnteredPlayMode)
{
SetStage(RebuildStage.WaitSceneLoad);
Progress("WaitSceneLoad...", 0.9f);
return;
}
if (state == PlayModeStateChange.ExitingEditMode)
{
SetStage(RebuildStage.WaitSceneLoad);
Progress("WaitSceneLoad...", 0.9f);
return;
}
}
}
private static void Progress(string msg, float progress)
{
if (string.IsNullOrEmpty(msg))
{
EditorUtility.ClearProgressBar();
return;
}
var time = EditorApplication.timeSinceStartup - GetStartTime();
var display = string.Format("{0} ({1:F2} seconds)", msg, time);
EditorUtility.DisplayProgressBar("Rebuilding", display, progress);
}
public static void Request()
{
SetStage(RebuildStage.Requested);
TouchStartTime();
}
public static RebuildStage GetStage()
{
var stage = EditorPrefs.GetInt("RebuildStage", 0);
return (RebuildStage)stage;
}
public static void SetStage(RebuildStage stage)
{
Debug.LogFormat("SetStage: {0}", stage);
EditorPrefs.SetInt("RebuildStage", (int)stage);
}
public static float GetStartTime()
{
var start = EditorPrefs.GetFloat("RebuildStart", (float)EditorApplication.timeSinceStartup);
return start;
}
public static void TouchStartTime()
{
EditorPrefs.SetFloat("RebuildStart", (float)EditorApplication.timeSinceStartup);
}
public static void OnUpdate()
{
var stage = GetStage();
//Debug.LogFormat("Update: stage: {0}", stage);
switch (stage)
{
case RebuildStage.None:
break;
case RebuildStage.Requested:
Progress("Wait Stop Playing...", 0.0f);
SetStage(RebuildStage.WaitStopPlaying);
EditorApplication.isPlaying = false;
break;
case RebuildStage.WaitStopPlaying:
if (EditorApplication.isUpdating)
return;
if (EditorApplication.isCompiling)
return;
if (EditorApplication.isPlaying)
return;
Progress("WaitAssetRefresh...", 0.1f);
SetStage(RebuildStage.WaitAssetRefresh);
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
break;
case RebuildStage.WaitAssetRefresh:
if (EditorApplication.isUpdating)
return;
if (EditorApplication.isCompiling)
return;
Progress("WaitPlayStart...", 0.2f);
SetStage(RebuildStage.WaitPlayStart);
EditorApplication.isPlaying = true;
break;
case RebuildStage.WaitPlayStart:
// handled in callback
break;
case RebuildStage.WaitSceneLoad:
var frameCount = Time.renderedFrameCount;
if (frameCount > 10)
{
Progress(null, 1.0f);
SetStage(RebuildStage.None);
}
break;
}
}
}
public class CustomEditorShortcuts
: MonoBehaviour
{
[MenuItem("Custom/Rebuild && Run %F5")]
private static void RebuildRun()
{
RebuildRunHelper.Request();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment