- Home /
Executing a script in edit mode
I have created a custom inspector for a script I made, and within this custom inspector there is a button which I want to use to "Test run" the script while in edit mode. The behavior I need is exactly like that of a particle system when it is selected during edit mode (so I know this HAS to be possible).
Is there a way of achieving the above mentioned behavior?
By the way, I have tried using the [ExecuteInEditMode]
attribute, but this only seems to call the update method when something in the editor changes or I manually move the object. I could be using it wrong, but there isn't much to it unless I completely missed something. If anybody has a link to a good example of this being used, I would appreciate it if it was linked here.
After a little more research I found out that placing and selecting a Particle system into the scene will cause my script's update method to get constantly called while in edit mode. Does anybody know how unity achieves this behavior? They must be calling some method that forces the editor to update all scripts with the [ExecuteInEditMode]
attribute.
I came across the trick where you call EditorUtility.SetDirty(target) within the Editor script's OnInspectorGUI method, but is this really the best way to get a script's Update method to get repeatedly called?
Answer by .sanders · Jan 22, 2012 at 04:36 AM
Alright I found a workaround for you which I think might work, is also elegant and might have the same result as the Particle Emitter in unity . Just write a CustomEditor for your component and define an OnEnable() and OnDisable() method on it. In the OnEnable you add a CallbackFuntion delegate on the EditorApplication.update event. And in the OnDisable you remove that CallbackFunction. Something like this:
[CustomEditor(typeof(MyScript))]
public class MyScriptEditor : Editor
{
private void CallbackFunction()
{
Debug.Log("updating...");
// Call the update of the MyScript
}
void OnEnable()
{
EditorApplication.update += CallbackFunction;
}
void OnDisable()
{
EditorApplication.update -= CallbackFunction;
}
}
So as long as you have selected the right GameObject, it's update will get called. I tried with the Debug.Log and got updates regularly. Try it and see if it works. You might also want to call the Awake() or Start() in the OnEnable() method (if needed)
Cheers! And let me know if this does the job for you.
To Question above, try something like this.
private void CallbackFunction()
{
$$anonymous$$yScript mTarget = target as $$anonymous$$yScript;
mTraget.Update();
}
As side note it can also be used to keep a coroutine alive in the editor.
Setting the target as dirty will make the editor call update and run other functions on the object, in my case 'IsRunning' is a variable used to indicate that the coroutine is active, if you need update to be called without a break just remove the if statement or use example above.
private void CallbackFunction()
{
$$anonymous$$yScript mTarget = target as $$anonymous$$yScript;
if (mTarget.isRunning) {
EditorUtility.SetDirty(mTarget);
}
}
Answer by .sanders · Jan 19, 2012 at 11:33 PM
I don't know if it's possible but can't you just call the Update() of the script in the Update() of the CustomEditor script? Either make the method public or use the sendMessage() to the corresponding GameObject.
So as long as the CustomEditor is visible (which is when you've selected a GameObject that has your script attached to it), your script will also execute it's Update() function. Of course you can tweak that afterwards as you like
Hope this helps, if this works let me know alright!
cheers
Thanks for the idea .sanders. Since my custom inspector class is deriving from Editor, it doesn't seem to have an actual Update method. Ins$$anonymous$$d I wrote my logic in OnInspectorGUI() which seems to behave the same way. I manually called the script's update loop to get my object to move, just like you suggested, and it works! The only problem was that it didn't really update the object within the scene as often as I initially hoped, so I ended up calling SceneView.RepaintAll() within the OnInspectorGUI method (after updating the object of course).
I am still curious as to how Unity makes the Particle Emitter work in edit mode, but I suppose that will be another question since your suggestion does the job.
Hmm it's strange indeed that the OnInspectorGUI() is not called that much. I would think it gets called as often as the OnGUI() in-game, which is twice every frame. I'll try and find that out. Can't think of anything else right now to get the Update() called for the GameObject as often as in running mode.
I'll get back to you.
@ThePunisher I think I might have found what you are looking for. Check the next answer I wrote...
Answer by -_-_-_-_-_ · Apr 26, 2016 at 06:43 AM
In the Scripting API, it was mentioned that [ExecuteInEditMode] will only call update if something has been changed, because there are no frames running in edit mode, but the regular UnityEngine.MonoBehavior.Update() is invoked each frame, and if are really no frames the regular Update() can't really be invoked by Unity. See this. And talking about Particles, they are simulated which means that while running, they're in their little local play mode with nothing else in it.
Your answer
Follow this Question
Related Questions
Catch a unity undo/redo event. 2 Answers
Why my ParticleSystem tree object loops correctly in edit mode, but only part of it in play mode? 0 Answers
Problem to moving objects with collider in edit mode 2 Answers
Control the way objects are selected in edit mode 0 Answers
Turn on Shuriken "Simulate" from script in Edit mode? 1 Answer