Search Unity

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

Discussion in 'Editor & General Support' started by Andy2222, Sep 27, 2013.

  1. Andy2222

    Andy2222

    Joined:
    Nov 4, 2009
    Posts:
    81
    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
     
    Last edited: Sep 27, 2013
  2. Andy2222

    Andy2222

    Joined:
    Nov 4, 2009
    Posts:
    81
    Here is a actual example of code that will break if u use this "hack" for grouping.

    From the UFPS framework inside vp_component:

    Code (csharp):
    1. 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.
     
    Last edited: Sep 30, 2013
  3. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,208
    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.
     
  4. Andy2222

    Andy2222

    Joined:
    Nov 4, 2009
    Posts:
    81
    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 :p

    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.
     
    Last edited: Sep 30, 2013
  5. chelnok

    chelnok

    Joined:
    Jul 2, 2012
    Posts:
    680
    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 :)

    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 :)
     
  6. Andy2222

    Andy2222

    Joined:
    Nov 4, 2009
    Posts:
    81
    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.
     
  7. chelnok

    chelnok

    Joined:
    Jul 2, 2012
    Posts:
    680
    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.
     
  8. Errorsatz

    Errorsatz

    Joined:
    Aug 8, 2012
    Posts:
    555
    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.
     
  9. Andy2222

    Andy2222

    Joined:
    Nov 4, 2009
    Posts:
    81
    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.
     
    Last edited: Oct 1, 2013
  10. BiomotionLab

    BiomotionLab

    Joined:
    Oct 9, 2018
    Posts:
    11
    Why not just add a script
    TurretBase
    to your turret's local root empty, and then inside the turrret hierarchy, call:

    Code (CSharp):
    1. GetComponentInParent<TurretBase>();