How to make Overlays dynamically update along with component?

Hi, I’m new to UI-Toolkit and the EditorTools/Overlay API, and I find it hard to use instead of IMGUI.

I’m trying to make an Overlay that shows up when you select a certain component. I want the overlay to update dynamically when tweaking some parameters on the component.

This component allocates a RenderTexture with multiple slice;

  • I want the image shown on the overlay to update when the Render Texture is updated
  • I want to have a slider that can display any slice in the Render Texture.

I can’t find any way to set an Image, source texture’s slice, and I can’t figure out how to change the Image reference when the component gets refreshed.

Here’s what I have now:

[EditorTool("GI Tool", typeof(GIManager)), Icon("d_debug")]
public class GITool : EditorTool
{
    [Overlay(displayName = "GI Debug Overlay", defaultDisplay = true), Icon("LightProbeProxyVolume Gizmo")]
    class GIOverlay : Overlay
    {
        internal GIManager _manager;

        public override VisualElement CreatePanelContent()
        {
            var root = new VisualElement();

            var tabView = new TabView();
            var tab1 = new Tab("Radiance");
            var tab2 = new Tab("Visibility");
                
            if(_manager != null)
            {
                tab1.Add(new UnityEngine.UIElements.Image() 
                {
                    image = _manager.RadianceTexture,
                });
                tab2.Add(new UnityEngine.UIElements.Image()
                {
                    image = _manager.RadianceTexture,
                });
            }
            else
            {
                root.Add(new Label("No GI Manager Selected"));
            }
                
            tabView.Add(tab1);
            tabView.Add(tab2);
            root.Add(tabView);
            return root;

        }
    }

    GIOverlay _overlay;

    public override void OnActivated()
    {
        SceneView.AddOverlayToActiveView(_overlay = new GIOverlay() { _manager = target as GIManager });
    }

    public override void OnWillBeDeactivated()
    {
        SceneView.RemoveOverlayFromActiveView(_overlay);
    }
}

Seems like overlays don’t expose the selected object they’re drawing for, though in the docs I can see that you can use an editor tool to add an overlay you construct yourself: Unity - Scripting API: Overlay (third example).

So I would use that to pass your targets into the overlay. From there you would use SerializedObject data binding to track changes in the component’s serialized data: Unity - Manual: Introduction to SerializedObject data binding