Any way to get the list of children of a game object?

There is set_parent method, but no get_parent or get_children. Since go.delete() can recursively delete all children, there must be an internal list of all the children.

Is it possible to get access to this list and request parent and children of a game object?

5 Likes

Well, it’s been left out by design.

The rationale being that it’s all too easy to create code that traverses the scene graph, to get this or that node, in an update. This use case was very real and huge timesink at a previous games company some of us worked for.

Instead, you are encouraged to setup your structure beforehand, to know what item you want to interact with using urls.

7 Likes

Why can’t we be encouraged to set up structures with url usage and at the same time have an ability to get children/parent if needed? Have it implemented with a side note that it’s not performant and better avoided for speed.

My use case is grouping elements (go with model) together. It’s all working with my structure (add child, remove child), but having a native way of determining children can prevent certain bugs and ease development, for instance when one element could be in two groups or if it’s in one group and actually belong to a different go.

At least for debugging it could be very useful (check how many go in a scene and find stray ones).

5 Likes

Yes, for debugging that would be very useful at times.

3 Likes

I think it’s possible to use profiler for debug

2 Likes

Or DefPro: https://github.com/britzl/defpro

4 Likes

Still no get_parent or get_children_list?
Was thinking the same, if go.delete can go recursively then the list of children is there.

My current situation: I’m “forced” to use a collection proxy just in order to easily disable and enable it.
Knowing the list of GO children I could recursively disable any hierarchy, being a collection or part of it.

I can think of many uses of get_parent, get_childs… and this is actually something common basic access I have seen in game engines I have worked with.

2 Likes

I understand what you are saying and why you want it. But keeping track of the children yourself isn’t a lot of effort either, if you are spawning the objects with factory you can save them in a table, if they are already in a collection/game object you can add id’s in a list in your script. I presume that the creators of the engine haven’t added convenience functionality like this because it goes against the philosophy a bit - keep the engine small.

3 Likes

We talked about this recently. There is a go.set_parent() but no get parent. This is an inconsistent in the API as both exist for GUI nodes. You can expect go.get_parent() to be implemented.

Not really sure about getting children though.

4 Likes

I disagree. Is not only considerable effort, it also leads to uncomfortable amount of hard-coded strings. And I feel bad when adding too much data to the source code that could be kept on this nice editor we have.
Right now, while typing I’m working on a project where I have a hierarchy of 18 game objects, from a bigger collection. Later realized I need to disable them temporally and enable back.

To keep track, I should store a list of IDs. Right? Or there is a better way?.
Like:
group = { ‘root’, ‘object1’, ‘object2’, ‘thing’, ‘rect’, ‘stuff’, ‘foo’ … }

All the things that could happen later:

  • Changed my mind, I want to use better meaningful ID names on the editor. Need to go also to code and update.
  • Decided on the editor that I need to add/remove and object. Go to code again to update.
  • Moved an object to another hierarchy tree. Go to code to update, or it will be wrongly disabled/enabled.

If I have a go.get_children(). I only need to keep track of a single object: the root. And use recursive calls to apply any changes the hierarchy. Non of the issues described above will happen.

I don’t think adding a few more getters and setter for information that is already there on the engine (without adding new funcitonality) will add more than a few bytes.

Anyway our apps are growing the same amount or more of bytes when adding all this “tracking” code.

2 Likes

Here is my use case, which led me to this thread.

  • I have a set of gameobjects under a scroll_root parent object.
  • I move the scroll_root around instead of moving all the individual children.
  • I need to turn off the children which are outside the bounds of the screen

The way I would like to solve this is to just iterate over the list of children of the scroll_root object, find their bounds and enable/disable based on that. This is how I would do it in Unity.

I think what I have to do is either hardcode all the names of the objects to iterate through, which is fragile to typos, renaming and forgetting to add a new object to the list. Or I can put the enable/disable bounds checking into it’s own script and add that as a component to each child gameobject, which is still fragile to forgetting when adding a new object, and AFAIK you can’t add components to ‘game object files’, so I would need to add the component to the .go files, but these are used in other places where I don’t want this functionality, so then I have to enable/disable the script…

This feels like a lot of legwork for a pretty straightforward and common scenario: turning objects on when visible and off when offscreen.

3 Likes

Turning objects off outside the bounds of the screen is common for performance or object pooling purposes, or for visuals. In my case it’s a visual effect, which could more easily be solved by having a mask or clipping bounds for the sprites of the children gameobject, but AFAIK that is only available for GUI components not sprite components (unless I write my own stencil buffer shader).

1 Like

Definitely agree that a go.get_children() would be useful, especially since as mentioned above, this information is already registered with the engine. For dynamically created objects i don’t find it a big deal, I simply register newly made objects to their creator or to a module somewhere, whether parented or not, and i like that I have that kind of control through my own code. However, creating a collection as a “prefab,” or dropping nested GOs directly into a collection “scene/level” does not give you this opportunity, other than as you say, to manually enter names into a script, unless each GO has its own script, which I try to avoid whenever possible, controlling most objects via a higher level controller and/or module.

4 Likes

Thank you for all of the feedback. We are looking into a bigger feature to provide full inspection of the scene graph. The main purpose of this functionality is to use it for UI automation, test frameworks and editor and stand alone tools. As part of this we must also look at the whole get parent and get child/children functionality that the engine provides. It is not unlikely that you will see this functionality available in the engine during Q3.

The reason we have been reluctant to add this kind of functionality is the implication it has on performance. It is not a fast operation and not really something that should be used without caution. In general we don’t want to provide functionality that can be misused and cause performance problems for developers.

14 Likes

All of the use cases I found myself wanting to inspect the scene graph are at initialization stage. Performance at that moment is not important in most cases. While having that info about the scene allows me to reuse lot of code and create better design.

Even allows a level designer communicate something to the code without having to write a single line of Lua code. (or attaching more unnecessary scripts).

I’m back to this thread because just today I found myself again fighting with the fact that there is no way way to communicate anything from the Collection scene to the Script. The script has to know anything in advance.

Today case: I have several GUIs that are very similar, so all of them can be managed by a single gui_script, the only thing the scripts needs to know is who is the root node (or multiple root nodes).

Look what I had to do, before almost giving up :sweat_smile:
image
^ I created a Text node that will always named roots then I can parse the text property at initialization to know who are the root node names of the scene. “Solved.:joy:

Scene graph inspection could help us a lot with things like these.

I was also thinking about a “Table component”, an invisible component that just store key=values, I will elaborate better and post in another thread to see if more people are interested on this too.

Merry Christmas and Happy New Year! :partying_face:

6 Likes

I agree that would be very useful. As someone who has started learning defold, this is something I really miss from other systems/engines.
As an example:

There is now a method gui.get_tree() in Defold 1.4.8
It allows to get a node and all its children as a Lua table.

7 Likes