cybereality Argh, vocabulary, complete misunderstanding again, I'm not talking about the interface within my own project but Godot's interface.
Is there a way on the interface to check your parents and children at a glance?
Lethn Yes, that code is for the Godot editor interface. Try it.
- Edited
cybereality Okay, I think I'm starting to get you.
Did I set this up correctly?
Also, I've got the proper syntax I'm thinking of now:
https://docs.godotengine.org/en/3.1/classes/class_node.html#class-node-method-get-index
https://docs.godotengine.org/en/stable/classes/class_node.html#class-node-method-get-parent
get_parent().name
Wish I had found this sooner then I would have made way more sense, so what I'm thinking of would be your label idea but with get.index() and then get_parent().name as the result and as it turns out this should be possible.
Edit: You mentioned this earlier in the chat and I hadn't double checked, sorry about that.
Yes, you can do that. But you don't want a Control in a 3D game, unless you intend to display a HUD. What you want to is to right-click the Control, click Change Type, choose Spatial, then in the script, change the second line to read:
extends Spatial
You don't have to edit anything else. But you probably need to save everything and then close the editor and reopen this (you only need to do this the first time once). Then click the eye icon to the right of the name of that node to refresh the names after you do something.
Lethn This is how it should look if it's working.
In Object of type 'Spatial': Attempt to connect nonexistent signal 'hide' to method 'Spatial.update_numbers'.
Sorry, it should be like this:
tool
extends Spatial
func _ready():
connect("visibility_changed", self, "update_numbers")
func update_numbers():
if Engine.editor_hint:
number_children(self, 1)
func number_children(node, num):
var title = node.name
var idx = title.find("-")
if idx > 0:
title = title.substr(idx + 2)
node.name = str(num) + " - " + title
for child in node.get_children():
number_children(child, num)
num += 1
- Edited
cybereality It's doing stuff now, but this is how it's showing up for me. Is it because I'm 3D and you're 2D?
- Best Answerset by Lethn
I should have tested more. This should work.
tool
extends Spatial
func _ready():
connect("visibility_changed", self, "update_numbers")
func update_numbers():
if Engine.editor_hint:
if not visible:
number_children(self)
else:
clear_children(self)
func number_children(node):
var title = node.name
var idx = title.find("-")
if idx > 0:
title = title.substr(idx + 2)
node.name = str(node.get_index()) + " - " + title
for child in node.get_children():
number_children(child)
func clear_children(node):
var title = node.name
var idx = title.find("-")
if idx > 0:
title = title.substr(idx + 2)
node.name = title
for child in node.get_children():
clear_children(child)
cybereality Same problem unfortunately, also hiding the spatial now seems to crash the engine.
Maybe you have both scripts. Check that only the new one is there. If the old one is still there, remove it (by right clicking the root node and choosing Detach Script) then close the editor, open it again and Attach Script for the new script.
- Edited
cybereality Aha! Okay! It looks like what was going on was Godot didn't like me just copy and pasting the new code and overwriting the old one for some reason, deleted the file, restarted and now it's working. I like this setup a lot, I think this works as a proof of concept at least. I realise it might seem weird at first, but I hope it makes more sense now that it's all laid out like that. if you're working with lots of child objects it means you can quickly get the index you want without having to count down the hierarchy in your head or for that matter rely on printing out the index to check what is where.
- Edited
Lethn I'm just wondering why there isn't any kind of interface to more quickly check rather than doing a print in code. I just had a moment because I realised how many nodes I often end up working with and sometimes I wonder if it couldn't be easier to keep track of child indexes.
You can replace 'get_child(x)' where 'x' is the child's index, with '$NODENAME' (which will autocomplete as you type based on child node names available) or 'get_node("NODENAME")' which largely removes the need to track anything by ID number in the way you are implying.
Also, in Godot the moment you select a different object in the main window, the selection in the Tree will change to reflect this. As such the tree always reflects which node is selected, and can thereby be referred to at any time to identify its parent.
The same is also true of Blender, however Blender does not automatically unscroll groups (for reasons). If you unscroll your armature, you should see it update here also as you select different bones, so you don't need to look in the 'Relations' section at all to see this.
I suppose if there were hundreds of children in the tree this would not immediately identify it's parent, but this I would imagine to be a pretty fringe issue and resolveable by relative paths/get_parent() anyway (i.e a child node already knows what its parent is, so you don't need to check it manually when writing child code).
- Edited
I'm happy the script is working. However, I very rarely look for stuff in the tree. I make sure all my nodes have sensible names that are clear what they are. These are some other things you can do that might help you if you are not familiar with Godot.
- Click on any object inside the viewport and press the F key. It will focus on that object.
- You can also click on the object name on the left Scene panel, then move the mouse into the viewport and press F. It will focus it as before.
- On the left (under Scene) there is a Filter text box. You can type in the name of an object you want, and it will highlight just that object and it's direct ancestors (meaning the parent, and the parent's parent, etc.). I believe this may be what you were looking for. You can also click it and use F as above to center it into the viewport.
cybereality Does this script need to be put into the code every time? Is it possible to make it a plugin that would work in any project?
Yes, it could be a plug-in. But I would have to rethink it, it's kind of a hack the way it works now. Because it is renaming the nodes. Meaning if you use $ or get_node() it won't work while the numbers are displayed (that is why I added the visibility toggle). Though with a plug-in I could create a new dock window with different features, for example something more similar to Blender or whatever, which doesn't affect the main scene tree (it would just be a visual thing). Not sure there is high demand, but it wouldn't be hard to do.
cybereality Not sure there is high demand, but it wouldn't be hard to do.
The convenience of some functions is not always obvious. Sometimes they seem to be not very necessary, but when a person starts using them, he does not understand how he could do without them before.
- Edited
To explain a bit more on the 'why' of me wanting this. It's a convenience thing and I think it helps with visualising the hierarchy better because 99% of the time I'm doing what you see with that script in my head anyway.
Yes, you can use code, but who the hell wants to write print(get_child(0).name) or print(get_index) etc. every time just to find out what index position a certain node belongs to? When your projects expand and you have more and more complicated hierarchies, it's inevitable this becomes fiddly and since this is an open source project I thought I'd ask around about it.
Now obviously from the perspective of keeping it clean, keeping this option tucked away is a good idea, I'd view it as a bit of a debug feature, hope this helps people understand where my line of thinking is with this idea.
- Edited
Lethn because 99% of the time I'm doing what you see with that script in my head anyway
This is the bit I don't get though. Referring to a named variable that can be called by its name directly instead by it's position in an array just seems to be more work, not less. You may as well name the node '0', '1', '2' etc. in the scene tree if that is the case.
I mean:
Get_Child(4)
vs.
$BLWheel
or Get_Node("BLWheel")
I know which makes more sense/is more readable to me, and as an added benefit is order agnostic. Even if I were iterating a list of children and wanted to do something conditionally based on the nodes name, I would use the .name attribute over it's position in the array, which may always be subject to change based on logic elsewhere; or use groups.
Anyway each to their own, the tldr; is that the editor is written in the engine, so absolutely can be modified to suit your specific needs through writing your own plugin/tool scripts as described above.
There is almost never a need to know the child index, except for maybe 2D GUI, where the ordering affects the drawing order (but even then you could use z-index if you wanted). For 3D, all children of a given parent are on the same layer. There can be 100 children, they are essentially all equal, and the indexing does not affect the drawing in any way. It does affect the order of certain code (such as when _ready is called) but you should never code assuming a fixed index, as you may move the order in the editor, or manually if objects are created or destroyed in code, so it is a bad practice.
So there is no practical reason or any tangible benefit to knowing if a child index is 3 or 4873239. It makes no difference. And if you have so many nodes that you can't find them or see what they are, that probably means it is a bad design. All the nodes should have clear names, and you can collapse a group of nodes into a Scene, if there are too many, as a form of organization. You should probably spend some time to learn how Godot works and the intending workflow because it may have been designed that way for a good reason.