How do you force a custom inspector to redraw?
Asked Answered
U

8

0

I have a custom editor inspector that I have labels that report data that gets sync via a custom button on the same inspector, this starts up WWW class to get the data. Once the data syncs and is posted into the value that the lable consumes the custom inspector.

However, it does not refresh the lable value unless I click on the inspector window again.

Is it possible to force the inspector to redraw at the time the values changes?

Ununa answered 7/2 at 19:25 Comment(0)
A
0

Call Repaint()

Absorber answered 7/2 at 19:21 Comment(2)

Good but Editor.Repaint() is only for scripts using UnityEditor I want to have game code (non editor scripts) while running to trigger this event repaint event so can watch the gameplay values refresh in editor. Does the editor have an update that can check a value to see if Editor repaint is needed? It seems I could do this with an EditorWindow as it has update functions but what about extending the editor class?

Ununa

For scriptable objects you also need to call serializedObject.Update(); at the beginning of the OnInspectorGUI() so that the data updates. EditorUtility.SetDirty() for some reason is not sufficient.

Miosis
U
0

Ok here we go, adding it to the OnInspectorGUI call makes it refresh.

public class UserInspector : Editor 
{
    public override void OnInspectorGUI()
    {
        Repaint();
        //Draw code logic here
    }
}
Ununa answered 7/2 at 19:23 Comment(2)

This will actually lead to a redraw on every frame, since editor-scripts do not support coroutines, this is your only choice. You could stop calling Repaint(); when www is ready (would improve GUI performance ;)

Absorber

Noted, the object that the inspector is drawing will have a flag set when data has been changed so it is not always called.

Ununa
C
0

If you need to refresh an inspector Window while Unity is playing, you can simply change the value of a serialized field in its target, and the Inspector will repaint automatically. See my self-answered question here: Refreshing custom Inspector window while playing - Questions & Answers - Unity Discussions

Concealment answered 17/10, 2012 at 17:59 Comment(0)
T
0

Here’s a technique I’ve used for getting game code to call editor code. Rather than calling directly (which you can’t do), you can create an event delegate in the game code to which the editor code attaches itself.

So for your component that wants to tell the editor code to repaint itself, add something like this:

public class MyComponent : MonoBehaviour
{
    // Declare the method signature of the delegate to call.
    // For a void method with no parameters you could just use System.Action.
    public delegate void RepaintAction();
  
    // Declare the event to which editor code will hook itself.
    public event RepaintAction WantRepaint;
  
    // This private method will invoke the event and thus the attached editor code.
    private void Repaint()
    {
        // If no handlers are attached to the event then don't invoke it.
        if (WantRepaint != null)
        {
            WantRepaint();
        }
    }

    ...
}

Then in your custom inspector, have it attach its Repaint method to this event:

[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor
{
    // I like having the typecast to my component in one place, instead of everywhere I refer to target.
    private MyComponent Target
    {
        get { return (MyComponent)target; }
    }
  
    // When you enable the inspector, attach to the game code that wants to call it.
    void OnEnable()
    {
        Target.WantRepaint += this.Repaint;
    }
  
    // And then detach on disable.
    void OnDisable()
    {
        Target.WantRepaint -= this.Repaint;
    }
  
    ...
}

And now whenever your game code (in MyComponent) calls Repaint, the call will get dispatched via the event hook-up into the inspector, and a repaint will happen. So you can call Repaint as often or as little as you like.

A similar approach can be used any time you want activity in game code to trigger results in editor code. (I usually wrap all the game code side of this in #if UNITY_EDITOR, so it gets compiled away in a build.)

Thoria answered 7/2 at 19:24 Comment(0)
T
0

I know this is old but I came looking for an answer to this and found that calling:

EditorUtility.SetDirty( target );

will refresh the editor every frame.

void OnInspectorGUI()
{
   //Logic
   EditorUtility.SetDirty( target );
}
Three answered 7/2 at 19:20 Comment(4)

I don't understand how this could work. If OnInspectorGUI were being called, wouldn't it refresh already? This would make more sense to me if you had an Update method in which you called SetDirty. Anyone tried this? DOES it actually work? EDIT: Okay, so I'm an idiot. It was easy enough to try it, and it DOES work, although I'm kinda baffled as to how. I guess maybe the editor base class holds a deep copy of its target?

Kare

@________ It works great Thanks!!

Blackbeard

Still works like a charm in 2018.2.5f1, thank you!

Imam

Don't use this to redraw an inspector. SetDirty is intended to mark an asset as having changes that need to be saved by Unity. In the past it could also be used to mark GameObjects dirty, which would dirty the scene, but should no longer be used for this purpose. Incidentally this will also force a repaint, but this is only a side-effect and should not be misused like this. Call Repaint() on the editor instance instead. Or, if you don't have access to the instance, use UnityEditorInternal.InternalEditorUtility.RepaintAllViews();

Saleh
O
0

This was probably not available when the question was asked. But this is my recommended way:

[CustomEditor(typeof(MyType))]
public class MyTypeInspector : Editor
{
    public override bool RequiresConstantRepaint()
    {
        return true;
    }
  
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
  
        // Draw stuff
    }
}
Ophthalmia answered 7/2 at 19:24 Comment(2)

This is what I was looking for. Even void Update() { Repaint(); } didn't work for me. This did. Thank you!

Toscano

what is the difference between public override bool RequiresConstantRepaint() { return true; } and Repaint() ? And i also wonder its performance. :/

Openhearth
S
0

Posting this here since this is the closest match to my search: “unity refresh inspector”.

In my particular case I was trying to refresh the inspector view from PreferencesGUI. I tried inheriting Editor, but to access Repaint it needs to be called from a static class, which is what PreferencesGUI needs to be declared as. Anyway, the simplest solution for me was to use this:

public static PreferencesGUI ()
{
    ...preferences source code here
    
    // tell the inspector to redraw
    if(Selection.activeTransform != null)
    EditorUtility.SetDirty(Selection.activeTransform);
}

Hope this helps someone else out there…

Suboceanic answered 7/2 at 19:23 Comment(0)
B
0

This thread is very old, but here’s an another alternative to Repaint() and SetDirty(yourObject) for anyone with a similar problem to me:
EditorUtility.SetDirty(**yourWindow**)

Example:

EditorUtility.SetDirty(EditorWindow.focusedWindow);

It has a similar effect to EditorUtility.SetDirty(yourObject);, but it won’t dirty your scene/prefab.

This was useful for me to force the Inspector to reconsider the value of HideFlags for each individual component of an inspected GameObject.

Bedad answered 7/2 at 19:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.