How to easily debug draw stuff in the editor

Godot Version

4.3

Question

I have a class with some information (rectangles) I’d like to draw in the scene. Many scenes extend this class and they have sprites as children.
Godot has @tool and _draw(), and you can queue_redraw() in _process() if Engine.is_editor_hint(). But this draws before/behind all the sprites. It appears that there is no function that draws after that.

The way to do it seems to be to make a node with a higher z order or just further down in the hierarchy and do the debug drawing there but I don’t want to do that. It’s a pain. It’s a lot of faff and I have to delete the objects when the scene is instantiated in the real game.

Moreover, I can’t even get that to work. I’ve tried all sorts, but right now I have my class as a @tool, and in _process() I check if it’s the editor, and if it is, I see if I have a child called “DebugDraw” and if I don’t, I instantiate a debug draw scene and add it as a child. That scene is a node with a debug draw script on it that draws information from the parent. what I’m finding is that the inner code below is running every frame, so obviously something is going wrong.

Can anyone help? Also is there a feature request for something like “_scene_draw” or “_post_draw” I can bump / +1? It seems like a really basic thing that would help a lot.

@tool

func _process(_delta: float) -> void:	
	if Engine.is_editor_hint() and not find_child("DebugDraw"):
		var n = load("res://Scenes/geo_debug_draw.tscn").instantiate()
		n.name = "DebugDraw"
		add_child(n)
		# this code runs every frame in the editor

Okay this code works better. You have to set the name AFTER adding it. And the find_child function doesn’t find children that were added but which aren’t in the scene hierarchy, so you have to set the owner too (very odd behaviour imo)


func _process(_delta: float) -> void:	
	if Engine.is_editor_hint() and not find_child("DebugDraw"):
		var n : Node2D = load("res://Scenes/geo_debug_draw.tscn").instantiate()
		add_child(n)
		n.name = "DebugDraw"
		n.owner = self

Nevertheless, I don’t want to go to the trouble of creating a new debug script, a new debug node, and a new debug scene, plus all this boilerplate every time I have some data I want to draw. Isn’t there an easier way?