Open IntangibleMatter opened 2 months ago
You can hack it around by finding the snap dialog in scene tree and reading its values.
You can hack it around by finding the snap dialog in scene tree and reading its values.
This is a good temporary solution and I thank you for it, but it's still a needless hack considering how common this use case is for 2D plugins.
For anyone who comes across this in future and wants to use this, here's a version of the code working in Godot 4.3.0
var snap_enabled: bool = false
var snap_dimensions: Vector2 = Vector2.ZERO
var snap_offset: Vector2 = Vector2.ZERO
func _ready() -> void:
connect_to_snap()
func connect_to_snap() -> void:
if not Engine.is_editor_hint():
return
var snap: Node = EditorInterface.get_editor_main_screen()\
.get_child(0).get_child(2).get_child(0).get_child(0)
# this is a terrible line of code but I don't have a better way to do it
var snaptoggle: Button = EditorInterface.get_editor_main_screen().\
get_child(0).get_child(0).get_child(0).get_child(0).get_child(12)
snap_enabled = snaptoggle.button_pressed
snaptoggle.toggled.connect(func(tog: bool) -> void: snap_enabled = tog)
# grid offset x
snap.get_child(1).value_changed.connect(func(val: float) -> void: snap_offset.x = val)
# grid offset y
snap.get_child(2).value_changed.connect(func(val: float) -> void: snap_offset.y = val)
snap_offset = Vector2(snap.get_child(1).value, snap.get_child(2).value)
# grid snap x
snap.get_child(7).value_changed.connect(func(val: float) -> void: snap_dimensions.y = val)
# grid snap y
snap.get_child(8).value_changed.connect(func(val: float) -> void: snap_dimensions.y = val)
snap_dimensions = Vector2(snap.get_child(7).value, snap.get_child(8).value)
This code will break if any of the relevant nodes are offset in the tree, but this is the only way I could find to do it without being dependent on using .filter()
and searching for exact strings, which isn't friendly to using other languages in the editor. Again, terrible. This is why there should be an easier way to access these variables. Hope this helps anyone in the future!
Finding base controls can be more reliable:
func nice_find_child(parent: Node, child: String) -> Node:
return parent.find_child("*%s*" % child, true, false)
func connect_to_snap() -> void:
var snap := nice_find_child(EditorInterface.get_base_control(), "SnapDialog") # SnapDialog
snap = nice_find_child(snap_grid, "GridContainer") # SpinBox container.
var snap_toggle := nice_find_child(EditorInterface.get_base_control(), "CanvasItemEditor") # 2D editor.
snap_toggle = nice_find_child(snap_toggle, "HBoxContainer") # Toolbar.
snap_toggle = snap_toggle.get_child(12) # Snap button.
You can also avoid get_child()
by implementing a method that returns nth child of given type.
While it's still a hack, it's a bit more resilient to hierarchy changes.
I actually started out by using find_child()
, but it wouldn't find the nodes that I wanted it to do so (likely due to weird stuff with internal children or something), so I used this method instead, though I'll take another look.
Again, while it's good to have a method to do so, something this important for 2D editor plugins shouldn't be so hacky.
Describe the project you are working on
A plugin with a node that has custom handles for scaling/moving in the editor.
Describe the problem or limitation you are having in your project
There is no way to access grid snap to force the item to snap to the grid by default
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Implement some sort of
get_grid_snap()
function on EditorPlugin, EditorInterface, or the otherwise most relevant class.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
You would call a function to get the snapping intervals, as well as whether snap is enabled/disabled.
If this enhancement will not be used often, can it be worked around with a few lines of script?
Nope, you need to implement an entire grid system yourself, which is generally much more confusing to people using the plugin.
Is there a reason why this should be core and not an add-on in the asset library?
Core editor functionality.