- Home /
Repainting an EditorWindow when it's not the current focus?
I am currently working on a custom EditorWindow for a particular type of GameObject. When I select different objects in the Hierarchy window, the custom window is updated to edit this new object.
This all works fine, except the custom window doesn't redraw until I mouse-over it again. I've tried manually calling Repaint() on the window (didn't work), looked through the documentation and didn't see anything, so now I'm asking here.
How can I repaint a custom EditorWindow when it's not the active focus?
Thanks in advance.
Answer by spolglase · Jan 17, 2012 at 09:11 PM
I've found that adding Repaint() to the Update function of your EditorWindow does the trick. This also has the added effect of repainting the editor window way more often than it does normally which I also found handy in my case.
public void Update()
{
// This is necessary to make the framerate normal for the editor window.
Repaint();
}
I suppose if you want your Repaint to be less intrusive you could put it in EditorWindow.OnInspectorUpdate() because it only gets called 10 times per second. That would probably be better for performance.
public void OnInspectorUpdate()
{
// This will only get called 10 times per second.
Repaint();
}
Years later, but this was still a life-saver. Thanks so much!
Answer by jbourrie · Dec 18, 2010 at 11:52 PM
...it always seems to work this way, doesn't it? I ask the question after hunting through all the docs, then the minute I post I find the answer :)
For anyone looking at this in the future, EditorWindow.OnGUI() appears to only get called when the window is focused. Moving the Repaint() to EditorWindow.OnSelectionChanged() worked.
Answer by fadden · Oct 22, 2015 at 10:11 PM
I have an EditorWindow
for a particular type of object. I found that it generally redrew when needed if I did this:
// Called when the item selected in the inspector changes. This only fires when our
// editor window is visible.
void OnSelectionChange() {
m_selectedObj = GetSelection();
Repaint();
}
// OnSelectionChange() only fires when the window is visible. We need to grab it
// when the window comes back into view. I don't think OnFocus is quite right, since
// in theory the window could become visible without being focused, but in practice
// it works (and there's nothing better).
//
// Because the window is returning to visibility, Repaint() is usually redundant.
// However, if we make changes in Visual Studio and then return to Unity, we do get
// an OnFocus without a subsequent repaint.
void OnFocus() {
m_selectedObj = GetSelection();
Repaint();
}
The GetSelection()
method is using Selection.activeGameObject()
to grab whatever is currently selected, setting it to null
if it doesn't contain my target class as a component.
This works well in terms of being able to move around and select different objects, and it even refreshes if I update the editor code and return to Unity. It fails in one significant aspect though: if you change values in the inspector window, the editor window doesn't get notified, and doesn't redraw.
So it seems that calling Repaint()
from OnInspectorUpdate()
is necessary, which is rather annoying since it means the window is redrawing at 10x per second even when you're not doing anything. I don't see a way around this though.
(Edit: If you check for changes, and only call Repaint() when the object has been updated, you can avoid the full cost of the repaint. And I suppose the underlying object could have an event that the EditorWindow could subscribe to when the selection changes, and then a CustomEditor could fire that event whenever OnInspectorGUI runs...)