Zylann / godot_editor_debugger_plugin

A plugin to inspect the editor's scene tree itself, within the editor.
190 stars 20 forks source link

Add the ability to get the node's child path indices #9

Closed ryevdokimov closed 5 months ago

ryevdokimov commented 7 months ago

I was working on an editor plugin where I needed to modify specific UI elements that weren't easy to traverse to. Absolute path doesn't work because the name of the node can vary per session even within the same version of Godot. So, I modified this plugin to give it this ability. Others may find it useful.

https://github.com/Zylann/godot_editor_debugger_plugin/assets/105675984/2a33423b-ca85-4f24-b504-bb146acd6ab3

Zylann commented 5 months ago

It's starting to become quite a lot of "copy node" path menus due to peoples various random needs... this one in particular sounds very hacky and can break extremely easily. It really depends on the node you're getting, because indices can also change at runtime for plenty of reasons (Different children order in future versions, UI rebuilding, sorting, elements brough to front...) and you won't easily know when that happens if the query happens to return the same node type.

Regarding the implementation, I'm not sure you should bother with the string path here. If you want the indices, they can be obtained by simply using Node.get_index and recursing back up to the root, doesn't it?

ryevdokimov commented 5 months ago

It's starting to become quite a lot of "copy node" path menus due to peoples various random needs... this one in particular sounds very hacky, it really depends on the node you're getting, because indices can also change at runtime for a variety of reasons (UI rebuilding, sorting, element brough to front...)

Understood, but at least those factors are under your control, and you can compensate. I would argue the other "copy node" functions doesn't really work because there is no guarantee at all these nodes will be the same across sessions, there isn't a way to mitigate this.

Regarding the implementation, I'm not sure you should bother with the string path here. If you want the indices, they can be obtained by simply using Node.get_index and recursing back up to the root, doesn't it?

How would you get the Node to get index in the first?

Zylann commented 5 months ago

How would you get the Node to get index in the first?

What do you mean?

static func get_node_index_path(node: Node) -> PackedInt32Array:
    var ipath := PackedInt32Array()

    while node.get_parent() != null:
        ipath.append(node.get_index(true))
        node = node.get_parent()

    ipath.reverse()
    return ipath

static func get_node_by_ipath(ipath: PackedInt32Array) -> Node:
    var node = get_tree().root
    for i in ipath:
        node = node.get_child(i, true)
    return node

static func make_code_to_get_node_by_indices(ipath: PackedInt32Array) -> String:
    var code = "get_tree().root"
    for i in ipath:
        code += str(".get_child(", i, ")")
    return code

Untested, but just to illustrate my point

ryevdokimov commented 5 months ago

Ah gotcha, I initially misunderstood.

Yeah, I can look into refactoring it if you'd like, assuming you want this feature. Otherwise feel free to close.

ryevdokimov commented 5 months ago

I went ahead and tested what you wrote, and it works fine, so I updated the PR with it.

Zylann commented 5 months ago

Thanks!