Skip to content

Instantly share code, notes, and snippets.

@Jakob-PB
Last active February 8, 2019 09:18
Show Gist options
  • Select an option

  • Save Jakob-PB/b04fbbedb066fb3974b27201dc1cbb3c to your computer and use it in GitHub Desktop.

Select an option

Save Jakob-PB/b04fbbedb066fb3974b27201dc1cbb3c to your computer and use it in GitHub Desktop.

Revisions

  1. Jakob-PB revised this gist Feb 8, 2019. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion RenameDuplicatesMenuItems.cs
    Original file line number Diff line number Diff line change
    @@ -137,6 +137,7 @@ private static void recursivelyNameDuplicates(GameObject parent, bool removeNumb
    // Sort the children list by order in the hierarchy
    var sortedChildren = children.OrderBy(gameObj => gameObj.transform.GetSiblingIndex()).ToArray();

    // Decide whether to maintain a global or sibling only game object name count
    List<GameObjectName> nameList;
    if (useSiblingPosition)
    {
    @@ -150,7 +151,7 @@ private static void recursivelyNameDuplicates(GameObject parent, bool removeNumb
    // Rename the children based on the sorted order
    foreach (GameObject gObj in sortedChildren)
    {
    // Cut the copy number off if the game object name has one
    // Cut the duplication number off if the game object name has one
    if (gObj.name.EndsWith(")"))
    {
    int stringIndex = gObj.name.IndexOf("(");
  2. Jakob-PB revised this gist Feb 8, 2019. 1 changed file with 29 additions and 3 deletions.
    32 changes: 29 additions & 3 deletions RenameDuplicatesMenuItems.cs
    Original file line number Diff line number Diff line change
    @@ -29,13 +29,17 @@
    using System.Linq;
    using System.Collections.Generic;

    /// <summary>
    /// A small Unity editor utility for removing, restoring, or adjusting the default naming scheme for duplicate game objects.
    /// </summary>
    ///
    public class RenameDuplicatesMenuItems
    {
    /// <summary>
    /// Stores data about a game object name along with the number of game objects with that name.
    /// </summary>
    ///
    public class GameObjectName
    ///
    private class GameObjectName
    {
    public string name;
    public int count;
    @@ -49,7 +53,15 @@ public GameObjectName(string name, int count)

    private static List<GameObjectName> gameObjectNameList;

    [MenuItem("Tools/Recalculate Duplicate Numbering/Based On Hierarchy Position")]
    /// <summary>
    /// Appends a new duplication number (e.g. "GameObject (3)") for every game object in the scene based on position in the hierarchy.
    /// ^^^
    /// <para> Position in the hierarchy is from top to bottom without regard for parent/child relationships.
    /// In other words, the ordering is based on a flattened version of the hierarchy. Every copy of a game object
    /// will have a unique number appended. </para>
    /// </summary>
    ///
    [MenuItem("Tools/Recalculate Duplicate Numbering/Based On Hierarchy Position (Unique)")]
    private static void renameDuplicates_Hierarchy()
    {
    gameObjectNameList = new List<GameObjectName>();
    @@ -60,6 +72,15 @@ private static void renameDuplicates_Hierarchy()
    }
    }

    /// <summary>
    /// Appends a new duplication number (e.g. "GameObject (3)") for every game object in the scene based on position among siblings.
    /// ^^^
    /// <para> Position among siblings is from top to bottom relative to their parent. Compared to the
    /// "Based On Hierarchy Position" option this method may create several game objects with
    /// the same duplication number in the scene. However, sibling game objects will always be
    /// uniquely numbered. </para>
    /// </summary>
    ///
    [MenuItem("Tools/Recalculate Duplicate Numbering/Based On Sibling Position")]
    private static void renameDuplicates_Sibling()
    {
    @@ -71,6 +92,11 @@ private static void renameDuplicates_Sibling()
    }
    }

    /// <summary>
    /// Removes the duplication numbering (e.g. "GameObject (3)") from every game object in the scene.
    /// ^^^
    /// </summary>
    ///
    [MenuItem("Tools/Remove Duplicate Numbering")]
    private static void removeDuplicateNumbering()
    {
  3. Jakob-PB created this gist Feb 8, 2019.
    175 changes: 175 additions & 0 deletions RenameDuplicatesMenuItems.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,175 @@
    /**
    * MIT License
    *
    * Copyright (c) 2019 Jakob Bjerkness
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy
    * of this software and associated documentation files (the "Software"), to deal
    * in the Software without restriction, including without limitation the rights
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    * copies of the Software, and to permit persons to whom the Software is
    * furnished to do so, subject to the following conditions:
    *
    * The above copyright notice and this permission notice shall be included in all
    * copies or substantial portions of the Software.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    * SOFTWARE.
    *
    **/

    using UnityEngine;
    using UnityEditor;

    using System.Linq;
    using System.Collections.Generic;

    public class RenameDuplicatesMenuItems
    {
    /// <summary>
    /// Stores data about a game object name along with the number of game objects with that name.
    /// </summary>
    ///
    public class GameObjectName
    {
    public string name;
    public int count;

    public GameObjectName(string name, int count)
    {
    this.name = name;
    this.count = count;
    }
    }

    private static List<GameObjectName> gameObjectNameList;

    [MenuItem("Tools/Recalculate Duplicate Numbering/Based On Hierarchy Position")]
    private static void renameDuplicates_Hierarchy()
    {
    gameObjectNameList = new List<GameObjectName>();

    foreach (GameObject gObj in getSortedTopLevelGameObjects())
    {
    recursivelyNameDuplicates(gObj, false, false);
    }
    }

    [MenuItem("Tools/Recalculate Duplicate Numbering/Based On Sibling Position")]
    private static void renameDuplicates_Sibling()
    {
    gameObjectNameList = new List<GameObjectName>();

    foreach (GameObject gObj in getSortedTopLevelGameObjects())
    {
    recursivelyNameDuplicates(gObj, false, true);
    }
    }

    [MenuItem("Tools/Remove Duplicate Numbering")]
    private static void removeDuplicateNumbering()
    {
    gameObjectNameList = new List<GameObjectName>();

    foreach (GameObject gObj in getSortedTopLevelGameObjects())
    {
    recursivelyNameDuplicates(gObj, true, false);
    }
    }

    /// <summary>
    /// Returns an enumerable list that contains all the top level game objects
    /// in the hierarchy in order of their position in the hierarchy.
    /// </summary>
    ///
    private static IEnumerable<GameObject> getSortedTopLevelGameObjects()
    {
    var topLevelGameObjects = GameObject.FindObjectsOfType<GameObject>().Where(gameObj => gameObj.transform.parent == null);
    return topLevelGameObjects.OrderBy(gameObj => gameObj.transform.GetSiblingIndex()).ToArray();
    }

    /// <summary>
    /// Renames duplicates according to parameter options.
    /// </summary>
    ///
    private static void recursivelyNameDuplicates(GameObject parent, bool removeNumbering, bool useSiblingPosition)
    {
    if (parent.transform.childCount > 0)
    {
    // Add all the children of the parent to a list
    List<GameObject> children = new List<GameObject>();
    foreach (Transform child in parent.transform)
    {
    children.Add(child.gameObject);
    }

    // Sort the children list by order in the hierarchy
    var sortedChildren = children.OrderBy(gameObj => gameObj.transform.GetSiblingIndex()).ToArray();

    List<GameObjectName> nameList;
    if (useSiblingPosition)
    {
    nameList = new List<GameObjectName>();
    }
    else
    {
    nameList = gameObjectNameList;
    }

    // Rename the children based on the sorted order
    foreach (GameObject gObj in sortedChildren)
    {
    // Cut the copy number off if the game object name has one
    if (gObj.name.EndsWith(")"))
    {
    int stringIndex = gObj.name.IndexOf("(");

    // Remove extra spaces between name and iteration number
    for (int i = stringIndex; i > 0; i--)
    {
    if (gObj.name.ElementAt(i) == ' ')
    {
    stringIndex = i;
    }
    else
    {
    if (gObj.name.ElementAt(i) == '(') continue;
    else break;
    }
    }

    gObj.name = gObj.name.Substring(0, stringIndex);
    }

    if (!removeNumbering)
    {
    // Append the correct iteration number to the name
    bool listContainsName = false;
    foreach (GameObjectName gameObjectName in nameList)
    {
    if (gameObjectName.name == gObj.name)
    {
    gameObjectName.count += 1;
    gObj.name += " (" + gameObjectName.count + ")";

    listContainsName = true;
    }
    }
    if (!listContainsName)
    {
    nameList.Add(new GameObjectName(gObj.name, 0));
    //nameList.Add(new GameObjectName(gObj.name, 1));
    //gObj.name += " (1)";
    }
    }

    recursivelyNameDuplicates(gObj, removeNumbering, useSiblingPosition);
    }
    }
    }
    }