How to get a signal to go off when switching scenes in the editor from a tool script?

Godot Version

4.7.1.stable

Question

Hi, I’m working on a compositor shader effect, and it requires the exchange of data between two compositors, and the only way to do that is by making a singleton to hold references to the passed data (I’m specifically transmitting a rendered frame from one viewport to my main compositor effect, where the auxiliary compositor doesn’t even instance a glsl shader, it just grabs the texture RID and stores it on the singleton every render callback). The singleton is a @tool script, as well as every edited scene root.

The problem arises when opening multiple scenes, or multiple viewports in the editor, as that will change what camera is rendering the viewport and the reference to the current camera on the singleton becomes stale. I could check every frame if EditorInterface.get_editor_viewport_3d(i).get_camera_3d() == Singleton.aux_cameras[i], but that just seems like a waste of resources. I know a plugin has exactly that functionality, but it seems way too overkill to make a plugin just for one compositor effect to work in the editor…

Is there a solution that isn’t the plugin method? It’s really important to me that my shaders are previewable in the editor, for ease of implementation when I pass it on to the community.

I’ll just say the current solution is to EditorInterface.get_editor_viewport_3d(i).get_camera_3d() == Singleton.aux_cameras[i]every frame, for now.

Topic still open, tho, in case that changes.

From what I’ve found there’s no editor signal you can reach without a plugin. The scene_changed, scene_closed, and main_screen_changed signals all live on EditorPlugin, and EditorInterface doesn’t expose equivalents to a plain @tool script.

That said, the per frame check is much cheaper than it feels. Comparing get_camera_3d() against a stored reference is a couple of pointer lookups, and your aux compositor already runs code every render callback anyway, so folding the staleness check in there costs effectively nothing. And if you did want the signal, the plugin can be a ten line script in the same addon folder whose only job is connecting scene_changed to your singleton. Worth noting scene_changed has known edge cases (it can skip firing when replacing an empty scene), which makes the polling approach arguably the more robust one anyway.

I’d probably just do the check in the render callback and see how it goes.

Huh, thanks, then, I was already just doing that for the lack of a better method, but knowing it’s the optimal method is good.