I’m really stuck with my GDExtension project in Godot 4.3 and could use some help. I created this custom class called `Player` that extends `Control`, and my goal is to have it render a simple red rectangle in the editor, similar to how it works when I run my scene. I’ve been tinkering with it for hours, but I can’t seem to make it show up in the editor’s viewport – it only appears during runtime.
Here’s a quick overview of my code: I’ve overridden the `_draw()` method where I’m using `draw_rect()` to attempt to draw a rectangle. Everything is working perfectly when I play the scene, but as soon as I add the `Player` node to the scene in the editor, nothing happens. It’s almost like the editor ignores the `_draw()` method altogether.
I’ve also made sure to set `tool = true` in the `.gdextension` file. I thought that might solve the problem, but nope! I even placed `queue_redraw()` in both the constructor and the `_ready()` method, hoping it would trigger a redraw in the editor context, but that didn’t help either.
The rectangle is supposed to be a simple 100×100 red square, so there’s no complex logic at play. Just this basic shape that I want to be visible in the editor. Here’s the short version of my `_draw()` method:
“`cpp
void godot::Player::_draw() {
Rect2i rect{ 0, 0, 100, 100 };
Color color{ 255, 0, 0, 255 };
draw_rect(rect, color);
}
“`
It seems like I’ve covered all bases, and I’m not sure what’s missing. Is there any specific step or setting I might have overlooked that’s preventing the rectangle from rendering in the editor? Any tips or suggestions would be greatly appreciated. I’m feeling pretty frustrated and could really use some fresh eyes on this!
It sounds like you’re really close to getting it working! Since you’ve already overridden the
_draw()
method and made sure to usetool = true
, here are a few things you might want to double-check:Player
class is indeed extendingControl
and is set up to be a tool script. The GDExtension should havetool = true
defined in the binding, but make sure it’s correctly placed.queue_redraw()
, you might want to call it after the node is ready or during specific lifecycle events in the editor. Consider placing it in the_process()
method but make sure to wrap it with a check foris_inside_tree()
to prevent unnecessary calls if the node isn’t part of the scene yet.CanvasItem
, make sure that the parent node is also visible in the editor and that no visibility options are preventing the rendering.Lastly, just a small tip: try to simplify things as much as possible to isolate the issue. You might even create a small test project to see if the same code works outside of your main project suite.
Good luck! You’ve got this!
The main issue you’re encountering is likely related to Godot’s requirement for nodes to explicitly opt-in for editor drawing, especially when using GDExtension in C++. Even though you’ve correctly set
tool = true
in your GDExtension file, this alone isn’t always sufficient for nodes created through GDExtension. Additionally, your current rectangle color initialization usingColor(255, 0, 0, 255)
suggests RGBA values between 0 and 255, but Godot expects floats from 0.0 to 1.0. Therefore, updating your Color constructor to something likeColor(1.0, 0.0, 0.0, 1.0)
will correctly define a fully opaque red.Moreover, to ensure the node renders correctly within Godot’s editor viewport, consider explicitly checking if your node is running in the editor context using
Engine::get_singleton()->is_editor_hint()
in your code. Proper implementation involves overriding the_notification()
method to handleNOTIFICATION_ENTER_TREE
andNOTIFICATION_DRAW
, then callingqueue_redraw()
during these notifications. Also, make sure in your node’s constructor (where you bind the class methods), you’ve set Node flags appropriately withset_notify_transform(true)
. These changes explicitly signal the editor to consider and process your draw requests, ensuring your rectangle becomes visible within the editor viewport.