Problem with using "empty gameobject" to emulate editor/hierarchy folders/grouping.

Hi,

i just now noticed what the problem is if u use a “empty gameobject” to emulate editor/hierarchy folders. The problem is that instead of a editor only group, u just created a engine “visible” parent/child relation. This means any logic that works/expects a valid and logical parent/child relation will break! This is mostly the case if u use “transform.root” to check positions or to get hold of the logical “toplevel” parent.

As a example the root of a turret prefab, with moving parts and several child’s should be the turret itself and not a “turret group” or “my turrets” object, just because someone did decide he likes all turrets in the same editor foldout view.

So if u group your objects this way, u cant rely on “logical” expectations. This means the root object of a complex turret should be the platform or some toplevel object holding all the heavy turret logic and not the group objects “Turrets”. The problem is that its way to convenient to use “transform.root” to find a component, if u cant be sure how the actual parent/child hierarchy looks like. Often u don’t care at what child a particular component is, as long as it has one.

The other problem is that grouping is not absolute and might be user dependent, so a programmer might want different grouping from a artist, so a “good” grouping function can be changed per user and should therefor not impact the game at all, it should be editor only.

So i would advice against abusing a real parent/child relation to simulate abstract grouping.

So can we get a “real” grouping system?

Thx Andy

Here is a actual example of code that will break if u use this “hack” for grouping.

From the UFPS framework inside vp_component:

EventHandler = (vp_EventHandler)m_Transform.root.GetComponentInChildren(typeof(vp_EventHandler));

This means if 2 or more objects using a vp_EventHandler are “grouped”/parented, this logic will always only assign the vp_EventHandler reference from the first object found! This basically means all “vp_” logic will work with a wrong object.

I like using a game object as a grouping mechanism. This way, it behaves logically in the world. ie, moving the parent moves all the children. Scaling the parent scales them. Deactivating the parent, turns off all the children. etc.

Sounds like you are relying on assumptions when developing your code. What if you (or someone) wants to parent a turret to a tank? And put that tank on a ship? And move the ship around? This sounds all logice. But it sounds like the code in your example would break, because the ship would become the root.

Instead -
a) if you know your turret structure, use the actual relative parent properties to get to the root of the turret, instead of shortcutting to the root.
b) If you don’t know what the structure might be, then put a variable on the script, and assign the object.

This way you know what the root is without ambiguity.

As u named it correctly u are explicitly creating a “parent”, so yes the code needs to than understand possible valid configurations. I refer to the ill-advised use if “grouping” your hierarchy editor view like this. Often its not made clear that a “empty gameobject” cant be used as editor grouping, mainly because it is NOT empty and has a transform component :stuck_out_tongue:

Example:

Environment
__Static
____Walls
____Rooms
____QuestObjects
______MainQuest
______SideQuest
__Dynamic
____Turrets
____Destructables
____Doors
____Trigger

(sorry had problems with the formating)

I have seen similar “grouping” sometimes and i also was close enough to use this kind of setting up my editor hierarchy, since it seemed the only “fast” way to filter/group your hierarchy view in the editor. As i pointed out this should never be used, so u have to life with a cluttered, sorted by name flat main hierarchy for anything not really a valid parent/child relation.

The problem is that assume u have 50 Ai’s and 100 Turrets or any other high number of gameobjects in your scene, the only way u can work now is by using the “slow” filter field, while u might be tempted to create a “dummy parent” for your static objects.

Basically i want to point out, that parenting a gameobject has side-effects if u try to emulate other 3d programs editor “grouping” mechanism.

Thx Andy

PS: Basically its the way we use the word “grouping” in the one context it can mean “parenting” or creating a parent->child relation, in the other sense it means abstract user defined editor “grouping” of many “similar” objects or putting them in a “folder”. In the later context, that is unfortunately not possible inside the Unity editor.

You might be right about that, for example third party scripts might cause problems… however i want to point out that if you know your hierarcy, you dont need to use root, and if any third party script is problem, with grouping your own stuff it wont get too messy even if there was few exceptions. But if you dont group anything, you might end up facing side-effects like nervous breakdown :slight_smile:

When i start to work with new scene, i always add Empty Gameobject, rename it “__empty”, reset rotations and position, and then duplicate it …like ten times, just for starters (underscores so they stays nicely top, and are easy to rename to _floor, _walls etc, i also like to use other mark and chars like !!!Player, !!Enemies ?temp etc. I group everything, and i group groups too :slight_smile:

If u want to use OOP this is kinda hard, since every new hierarchy variant will break your code and u need a new version. The best OOP way i came up with is to tag those abstract “Folder/group” objects and write your own transform.GetRoot() extension method. In it u check for the “Folder” tag and handle it accordingly, ofc this only works in your own code.

hmm… havent had that kind of problem yet, but i’m learning C# at the moment, and trying to be more OOP… your way sounds pretty good. I might actually make my own GetRoot method like that.

This isn’t a Unity problem, this is a script problem.

Why are you using Transform.root and GetComponentInChildren anyway? That’s a very scattershot method to get a parent object, and I don’t recommend it. If you want to establish a relationship between a parent and child, there are several better ways:

  1. Have a direct reference as an inspector parameter, on one or the other.
  2. Have the parent object find the child and establish the connection.

Objects shouldn’t rely on being at the root of the hierarchy - if they do, something is wrong with your scripts.

We don’t establish a parent/child, we explicitly establish a child->root relationship.

Kinda blanket statement, from a hierarchy point of view, there is no difference to “assume” a child->parent or child->root relation. In both cases u “assume” a layout. The problem is adding editor only “empty objects” to it, just to improve your editor work-flow, that mess up your logical and valid object hierarchy.
So as pointed out don’t abuse “empty parents” as a means to emulate a editor “folder” and u can work with roots just fine.

Why not just add a script TurretBase to your turret’s local root empty, and then inside the turrret hierarchy, call:

GetComponentInParent<TurretBase>();