Grouping objects in the Hierarchy?

Heya, I am currently decorating my scene with various objects in Unity, but the Hierarchy is getting extremely cluttered, is there a way to create folders there to put environment objects in to keep it all tidy?
I am making a TDG so when the game is played the towers that get created clutter up the Hierarchy as well. So if there is any way to make a group, folder or anything that will not spam the Hierarchy, so do not have to scroll for 2 minutes to find 1 particular object :slight_smile:

Any help is appreciated thank you.

Here’s a little Unity editor script I use to group selected objects. Just save this as Assets/Editor/GroupCommand.cs. Use ‘Ctrl-G’ or ‘GameObject Menu > Group Selected’. It also supports Undo:

using UnityEditor;
using UnityEngine;

public static class GroupCommand
{
    [MenuItem("GameObject/Group Selected %g")]
    private static void GroupSelected()
    {
        if (!Selection.activeTransform) return;
        var go = new GameObject(Selection.activeTransform.name + " Group");
        Undo.RegisterCreatedObjectUndo(go, "Group Selected");
        go.transform.SetParent(Selection.activeTransform.parent, false);
        foreach (var transform in Selection.transforms) Undo.SetTransformParent(transform, go.transform, "Group Selected");
        Selection.activeGameObject = go;
    }
}

Yes there is, but they aren’t really folders. If you go to GameObject > Create Empty this will place an empty object on your scene as well as your Hierarchy, you can then drag particular objects into that without affecting your game at all.

Example:

You have a butt load of lights in your scene. You can then create a Game Empty and call it ‘Lights’ and then drag in all your lights into the object.

Think of it more like a ‘null’ object.

Hope that helps.

Actually a “empty” gameobject still has a transform (cant be removed), which means that any normal logic that works via “transform.root” will break. Given the complex child/component relation unity uses, i would not advice to use this “hack” to simulate folders/grouping.

Often its to complicated to sort out what child may or may not have a certain component, so its common practice to search from the transform.root, which in the case of those “folder” objects will result in wrong or unpredictable behavior.

What I do is group them in an empty Gameobject, which has a script that deletes itself on runtime.

using UnityEngine;
public class UnrootChildrenAndDeleteOnRunTime : MonoBehaviour {
	void Awake() {
		while (transform.childCount > 0) {
			transform.GetChild(0).parent = null;
		}
		Destroy(this.gameObject);
	}
}

Add this to the group’s root and you’re good to go!

I read that this could be prevented by setting the 0-Object (used as folder) to 0 0 0.

Create an empty gameobject and reset it’s position to (0,0,0). Drag this the project folder to create a prefab. Whenever you need to group objects, drag this prefab into the scene and it’s position will remain at the origin. Just make sure not to press apply on any of the groups.

Make a little empty script called (for instance and understanding) ‘WorkScriptTag’, that functions as, sort of, a Tag.
Find all your item that you want to ‘Group’ in your (most likely/up-to wast structured) hierarchy, and mark them.
Now, while all marked blue, press ‘Add component’, and add the ‘WorkScriptTag’ to all the items/gameobjects you want to group.
Go to ‘Project’ and right click the script and press the menu object; ‘Find References in Scene’.

This will result in you being able to handle + being-able-to-select all the given hierarchy GameObjects with the pseudo-‘Tag’ above (aka the ‘WorkScriptTag’ script attached).

An expansion on @bjennings76 's answer that uses the fill anchor for RectTransforms and maintains the order of grouped items:

public static class Shortcuts
{
    // http://answers.unity.com/answers/1793431/view.html
    [MenuItem("GameObject/Group Selected %g")]
    static void GroupSelected()
    {
        if (!Selection.activeTransform)
            return;
        var go = new GameObject(Selection.activeTransform.name + " Group");
        if (Selection.activeTransform is RectTransform)
        {
            var rect = go.AddComponent<RectTransform>();
            Maximize(rect);
        }
        Undo.RegisterCreatedObjectUndo(go, "Group Selected");

        go.transform.SetParent(Selection.activeTransform.parent, false);

        foreach (var transform in GetSelectedTransformsInOrder())
        {
            Undo.SetTransformParent(transform, go.transform, "Group Selected");
        }
        Selection.activeGameObject = go;
    }
    [MenuItem("GameObject/Group Selected %g", true)]
    static bool Validate_GroupSelected()
    {
        // Grouping only makes sense in a scene.
        return Selection.activeTransform != null;
    }

    static void Maximize(RectTransform t)
    {
        t.anchorMin = Vector2.zero;
        t.anchorMax = Vector2.one;
        t.pivot     = Vector2.one * 0.5f;
        t.sizeDelta = Vector2.zero;
    }

    static IEnumerable<Transform> GetSelectedTransformsInOrder()
    {
        // Selection order is arbitrary, so usually we sort by sibling
        // index to preserve ordering.
        return Selection.transforms
            .OrderBy(t => t.GetSiblingIndex());
    }

}

See setting other anchors here.