- Home /
EditorApplication.update resetting
I've set the EditorApplication callback to one of my own, and I've simply put a debug output in it, but as soon as an asset import happens, it only continues to function for a couple seconds afterwards. I subclassed the AssetPostprocessor.GetPostprocessOrder to hook it in from the start:
public class BackgroundUpdater : AssetPostprocessor { private static EditorApplication.CallbackFunction s_backgroundUpdateCB = new EditorApplication.CallbackFunction(BackgroundUpdateFunc);
public override int GetPostprocessOrder()
{
EditorApplication.update = s_backgroundUpdateCB;
return base.GetPostprocessOrder();
}
void BackgroundUpdateFunc()
{
Debug.Log("running background update func: " + EditorApplication.timeSinceStartup.ToString());
}
}
The problem I have with this is that everytime a script (any script, not even related to this one) is reimported/recompiled, either automatically or by the context menu from within Unity, My function stops outputting to the console, therefore it is ceasing to function as an update function...
Any ideas?
does anyone else in the unity world have any ideas? I'd offer a bounty but I only have 2 reputation points
Answer by Oncle-Ben · Feb 11, 2014 at 05:15 PM
You may set up a static class to be constructed each time the editor starts using the "InitializeOnLoad" attribute:
[InitializeOnLoad]
public static class MyStaticInitializer
{
static MyStaticInitializer()
{
// hook up your EditorApplication callbacks here
}
}
Word of warning, this will also be called each time a script is recompiled.
Answer by jonas-echterhoff · Jul 20, 2010 at 08:33 AM
When a script is imported, all the assemblies are recompiled, which makes all scripts reload, and resets this setup. You could try adding a static constructor to your script to set up your update function, as that will be called on assembly reload.
static BackgroundUpdater()
{
EditorApplication.update = s_backgroundUpdateCB;
}
in unity, static constructors only get called when something from that class is referenced. This can get fixed by adding an empty GetPostProcessOrder to that class, but then we're back at square one. Also, using the static constructor to set the update function still has the same problem where after a couple seconds, the update function just ceases to run.
Thanks for the good effort though!
Answer by MattMaker · Sep 12, 2011 at 02:56 AM
a better place for setting up and tearing down delegates is in a matching pair of OnEnabled() / OnDisabled functions.
instead of hooking anything relating to asset importing, I suggest putting this logic in a class that extends EditorWindow. Set your delegate in its OnEnable(), and unset it in OnDisable(). As long as your window exists, it will maintain the EditorApplication.update for you. When a recompile occurs, state is lost for just a moment, but it won't matter, because OnDisable and OnEnable will immediately be called, and things will continue as before.
Also, for safety's sake, use += to assign a delegate rather than =.
using UnityEngine;
using UnityEditor; using System.Collections;
//[InitializeOnLoad] public class EditorUpdateExample : EditorWindow {
private EditorApplication.CallbackFunction s_backgroundUpdateCB;
int executionCount = 0;
public void BackgroundUpdateFunc()
{
executionCount++;
Debug.Log("running background update func: " + EditorApplication.timeSinceStartup.ToString() + " " + (EditorApplication.isCompiling ? "compiling":"compiled") + " " + executionCount + " delegate: " + EditorApplication.update);
}
[ MenuItem( "Window/Background Updater" ) ]
public static void Launch()
{
EditorWindow window = GetWindow( typeof( EditorUpdateExample ) );
window.Show();
}
void OnEnable() {
Debug.Log(this + " OnEnable");
s_backgroundUpdateCB = new EditorApplication.CallbackFunction(BackgroundUpdateFunc);
EditorApplication.update += s_backgroundUpdateCB;
}
void OnDisable() {
Debug.Log(this + " OnDisable");
EditorApplication.update -= s_backgroundUpdateCB;
}
void OnProjectChange() {
Debug.LogWarning("OnProjectChange");
}
public void OnGUI()
{
EditorGUILayout.SelectableLabel((EditorApplication.update!=null)?EditorApplication.update.ToString():"NONE");
}
}