- Home /
Editor Script Reverts to Default State on Script Compilition
Hello everyone,
Here is my situation: I have an editor script which can perform a bunch of tasks. Whether or not it executes a function is based on some simple bools which by default are set to false. It's up to the user to set them to true. It looks something like this:
[ExecuteInEditMode]
class MyScript : MonoBehaviour
{
// user can change these from the inspector
public static bool performTaskA = false;
public static bool performTaskB = false;
// update function is added to EditorApplication.update
void static Update()
{
if (performTaskA)
taskA();
if (performTaskB)
taskB();
}
}
My problem is whenever a script (any script) is compiled, the bools get reset to their default value of false. How can I get around this?
Answer by rutter · Jul 10, 2014 at 09:46 PM
The editor will unload (and then reload) all assemblies when compiling; any transient data in memory will be lost during that process. That's by design, but it can bite you if you're not expecting it.
Editor scripts need to be aware of this, so they can compensate for it.
If you have a lot of data you need to serialize, you might do it using components in a scene, prefab, or ScriptableObject. I've also seen plugins that use JSON files and the like.
In your case, it looks like you have only a few simple fields, so you can probably use something lightweight like EditorPrefs?
EditorPrefs.SetBool("performTaskA", true);
...
if (EditorPrefs.GetBool("performTaskA")) {
taskA();
}
Beautiful answer. It seems that the EditorApplication.update delegate is also reset on script compile, how can I re-add my function after compilation?
Hmm. That delegate might be tricky, unless you have something in the scene that catches the problem. $$anonymous$$aybe a component with ExecuteInEdit$$anonymous$$ode?
Over time, I've tried to keep most of my editor scripts compartmentalized: they're active only when something specifically tells or needs them to be. In that line of thinking, something that's "always on" would usually be attached in the scene.
Answer by Bunny83 · Jul 10, 2014 at 10:06 PM
First of all that's not an editor script. It's a normal runtime script which just also runs at edit time (due to ExecuteInEditMode). MonoBehaviour scripts are always runtime scripts and will be part of your build game.
Besides that, when Unity recompiles a script, the whole scriptine environment is reloaded. So basically everything is lost. However Unity does serialize everything before the reload and recreates and deserializes everything afterwards, but the usual serialization rules apply. So static variables aren't serialized since they don't belong to an instance.
Using static variables can cause a lot of problems so it's generally better to use instance variables. Since you didn't showed the code which actually sets those booleans nor did you explain how those are actually set, i can't offer you a solution since there are many ways to do this. Give us some more information.
I did not know that about $$anonymous$$onoBehaviour scripts. Should I ins$$anonymous$$d drop the inheritance from $$anonymous$$onoBehaviour and do something like this:
class $$anonymous$$yScript
{
// ...
// Add Update to the EditorApplication.update delegate
static void Update()
{
//...
}
}
Regarding the values being reset, I will be switching to instance variables.
As I mentioned in my comment to rutter: it seems that the EditorApplication.update delegate is also reset on script compile, how can I re-add my function after compilation?
Thank you!
Yes you should drop the inheritance. If you just want to hook the update delegate, just use the "InitializeOnLoad" attribute on your class. It will force the static constructor to run as soon as the environment is ready.
See the manual on this topic:
http://docs.unity3d.com/$$anonymous$$anual/RunningEditorCodeOnLaunch.html
$$anonymous$$ay i ask what kind of task need to be run at a rate of 100 times per second? In most cases editor scripts are either custom inspectors, editorwindows or wizards. Using the update delegate will make you code run all the time while the editor is open.
Very nice answer! That is exactly what I need.
I didn't show it in my samples, but I actually created a simple timer class to control the frequency of execution, the pseudo code is as follows:
// called 100 times per second
static void Update()
{
// To my knowledge UnityEngine.Time only works in Game
// So I created a simple timer class which computes
// deltaTime based on EditorApplication.timeSinceStartup.
// If X amount of time has passed, the timer class sets
// a bool (xAmountOfTimeHasPassed) to true.
$$anonymous$$yTimerClass.update()
// In my case X = 0.033 seconds, so this flag will be
// true every 30 frames.
if ($$anonymous$$yTimerClass.xAmountOfTimeHasPassed)
{
// code to be executed every 30 frames here
// **sub the body of the update function in the original question here.**
}
}
$$anonymous$$y script relies on a plugin which interfaces with a special peripheral which provides another means of input for the editor.
Your answer
Follow this Question
Related Questions
default script editor now working anymore 0 Answers
Change Default Script Folder 5 Answers
Unity Script Editor Not Working 1 Answer
Script Editors for Unity 3 Answers
Hiding editor extension scripts 2 Answers