Prompt User to Name GameObject

Apologies if this is the wrong section, I couldn’t find one for editor scripts.

I’ve written my first editor script, which instantiates a new object and places it in the hierarchy. But I still have to find the object and edit its name. Is there a way I can make the cursor automatically appear in the new object’s name, so you can just start typing the name straight away? So you would select the menu option, and it creates an object, with the name already in ‘rename’ mode…

Thanks

I didn’t understood what you wanna do.
Instantiate a new GameObject, then ask user for the new gameObject name?
Or just instantiate a GameObject with the name already specified before click the menu button?
Anyway, you can change the GameObject name as you do at runtime mode. It works at editor mode since its serialized.

GameObject CloneGameObject(GameObject original, string newName)
{
    var clone = Instantiate(original);
    clone.name = newName;
    return newName;
}

GameObject CreateGameObject(string newName) => new GameObject(newName);

You know when you click a game object in the hierarchy to change it’s name. I want it to be in that mode as soon as it is created - so after the object is created, you can just start typing and it will update the name, without having to first select it and choose rename.

This:

static void CreateGameObject()
{
    //We select the HierarchyWindow in order to focus it.
    EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
    //We select the new GameObject we create as the selected one.
    Selection.activeGameObject = new GameObject();
    //When hierarchy is updated (it's not inmediated) we call Rename func.
    EditorApplication.hierarchyChanged += Rename;

    static void Rename()
    {           
        //we remove itself in order to not call it twice.
        EditorApplication.hierarchyChanged -= Rename;   
        //we press f2 virtually
        EditorWindow.focusedWindow.SendEvent(new Event { keyCode = KeyCode.F2, type = EventType.KeyDown });           
    }
}
1 Like

LMFAO just realized now this is exactly what GameObject/Create Empty button does. So you only have to call it ^^

static void CreateGameObject()
{
    EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
    EditorApplication.ExecuteMenuItem("GameObject/Create Empty");
}

Your code doesn’t work - maybe it works on a windows machine, but on MacBook not, even if I map rename to F2. Also, I’m not just creating a script to create an empty new game object. what would be the point? It seems there is a command called EngageRenameMode but it also isn’t working for me. Thanks anyway. I’ll try to figure it out.

Sincerely I don’t know why, but here works, using 2020.2.4f1 at windows…

I guess it’s because I’m on Unity 2019 on Mac. I copied your exact code, but it only create the object - it doesn’t initiate the rename.

I actually can’t do it this way, because I am creating a container object which I then populate with other objects, so I can’t just use the menu option anyway.

I found some posts about using a slight delay, but nothing I have tried works. Maybe it’s a 2019 or Mac thing…

If you can post a minimal example of your code I just can try it on my windows to confirm if it’s only a mac issue or there is maybe something more.

Hi @rubcc95

Code is below. It’s a simple script to let me select multiple objects and group them together into a single parent object easily - helps me clean up my scene.

It would save two clicks every time if I could just immediately start typing the game object name I want. It’s not a huge problem, but it would be nice. But mostly, I hate walking away from something not knowing why it doesn’t work!

The script works absolutely fine, apart from going into ‘rename’ mode. I’ve tried loads of different approaches using different combinations of the commented out code, including different ways of sending commands, even trying adding a listener…but nothing will work.

Any help would be appreciated…

using UnityEngine;
using UnityEditor;

public class GameObjectGrouper
{

    [MenuItem("Tools/SnowDay/Create Object", false, 10)]
    private static void CreateObject(MenuCommand menuCommand)
    {
        EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
        EditorApplication.ExecuteMenuItem("GameObject/Create Empty");
    }

    [MenuItem("Tools/SnowDay/Group Selected Objects")]
    private static void GroupSelectedObjectsMenu(MenuCommand menuCommand)
    {
        GroupSelectedObjects(menuCommand);
    }

    [MenuItem("Tools/SnowDay/Group Selected Objects", true)]
    private static bool GroupSelectedObjectsMenuValidation()
    {
        return Selection.gameObjects?.Length > 1;
    }

    [MenuItem("GameObject/Group Selected Objects", false, 10)]
    private static void GroupSelectedObjectsRightClick(MenuCommand menuCommand)
    {
        GroupSelectedObjects(menuCommand);
    }

    [MenuItem("GameObject/Group Selected Objects", true)]
    private static bool GroupSelectedObjectsRightClickValidation()
    {
        return Selection.gameObjects?.Length > 1;
    }

    private static void GroupSelectedObjects(MenuCommand menuCommand)
    {
        if (menuCommand.context != Selection.objects[0])
        {
            return;
        }

        if (Selection.gameObjects?.Length > 0)
        {

            var firstObject = Selection.gameObjects[0];
            var name = "Group - " + firstObject.name;
            int index = firstObject.transform.GetSiblingIndex();
            var parent = firstObject.transform.parent;


            //EditorApplication.update += EngageRenameMode;

            var gameObject = new GameObject();

            for (int i = 0; i < Selection.gameObjects.Length; i++)
            {
                Selection.gameObjects[i].transform.parent = gameObject.transform;
            }


            if (parent != null)
            {
                gameObject.transform.parent = parent.transform;
                gameObject.transform.SetSiblingIndex(index);
            }

            //var e = new Event { keyCode = KeyCode.F2, type = EventType.KeyDown };
            EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
            //EditorWindow.focusedWindow.SendEvent(e);
            Selection.objects = new Object[] { gameObject };
            //EditorApplication.ExecuteMenuItem("Edit/Rename");

        }

    }

    private static void EngageRenameMode()
    {
        //EditorApplication.update -= EngageRenameMode;
        //EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
        //EditorApplication.ExecuteMenuItem("Edit/Rename");
        var e = new Event { keyCode = KeyCode.F2, type = EventType.KeyDown };
        EditorWindow.focusedWindow.SendEvent(e);
    }

}
EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
EditorWindow.focusedWindow.SendEvent(new Event() { keyCode = KeyCode.F2, type = EventType.KeyDown });

This works for me. Just tried. You need to make your selection first though.

Try the Selection.activeGameObject = gameObject; instead of the Selection.objects = new Object[ ] { gameObject }; and then run the code above.

Hi @ - unfortunately that doesn’t work for me. I’m using 2019 on a MacBook, so maybe that’s why. F2 is not the default shortcut for rename on a Mac, but even if I set it as the shortcut in the preferences, this code still doesn’t engage rename mode.

Are you on PC? Did the code I posted work for you?

Ohhhh, that could explain why it doesn’t work, F2 is not F2 at mac probably… but this doesn’t explain why this method you pasted is not working.

    [MenuItem("Tools/SnowDay/Create Object", false, 10)]
    private static void CreateObject(MenuCommand menuCommand)
    {
        EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
        EditorApplication.ExecuteMenuItem("GameObject/Create Empty");
    }

Sry, I’m lost here, I can’t help more since I have not a mac to test this. Hope someone could help you.

Bingo!

Turns out it was nothing to do with Mac, or the method of sending commands, or the way of selecting objects.

It was just due to the time it takes to create the actual object in the hierarchy. I found this post. I guess maybe in an empty scene, just calling the rename works, but in a real scene with hundreds of objects, you need the delay.

Final code is here. It really speeds up organising my scenes. Thanks so much to those who helped.

using UnityEngine;
using UnityEditor;

public class GameObjectGrouper
{
    static double renameTime;


    [MenuItem("Tools/SnowDay/Create Object", false, 10)]
    private static void CreateObject(MenuCommand menuCommand)
    {
        EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
        EditorApplication.ExecuteMenuItem("GameObject/Create Empty");
    }

    [MenuItem("Tools/SnowDay/Group Selected Objects")]
    private static void GroupSelectedObjectsMenu(MenuCommand menuCommand)
    {
        GroupSelectedObjects(menuCommand, false);
    }

    [MenuItem("Tools/SnowDay/Group Selected Objects", true)]
    private static bool GroupSelectedObjectsMenuValidation()
    {
        return Selection.gameObjects?.Length > 1;
    }

    [MenuItem("GameObject/Group Selected Objects", false, 10)]
    private static void GroupSelectedObjectsRightClick(MenuCommand menuCommand)
    {
        GroupSelectedObjects(menuCommand,true);
    }

    [MenuItem("GameObject/Group Selected Objects", true)]
    private static bool GroupSelectedObjectsRightClickValidation()
    {
        return Selection.gameObjects?.Length > 1;
    }

    private static void GroupSelectedObjects(MenuCommand menuCommand, bool preventMultiSelect)
    {
        if (preventMultiSelect && menuCommand.context != Selection.objects[0])
        {
            return;
        }

        if (Selection.gameObjects?.Length > 0)
        {

            var firstObject = Selection.gameObjects[0];
            var index = firstObject.transform.GetSiblingIndex();
            var parent = firstObject.transform.parent;

            var gameObject = new GameObject();
            gameObject.name = "Group - " + firstObject.name;

            for (int i = 0; i < Selection.gameObjects.Length; i++)
            {
                Selection.gameObjects[i].transform.parent = gameObject.transform;
            }

            if (parent != null)
            {
                gameObject.transform.parent = parent.transform;
                gameObject.transform.SetSiblingIndex(index);
            }

            Selection.objects = new Object[] { gameObject };

            renameTime = EditorApplication.timeSinceStartup + 0.2d;
            EditorApplication.update += EngageRenameMode;

        }

    }

    private static void EngageRenameMode()
    {
        if (EditorApplication.timeSinceStartup >= renameTime)
        {
            EditorApplication.update -= EngageRenameMode;
            EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
            EditorApplication.ExecuteMenuItem("Edit/Rename");
        }
    }

}
3 Likes