困った時の自分用メモ

読んだ本を考察してメモったり、自分でいじった物の感想をメモったりする場。週1更新を目指します。

Unityの話~エディター拡張を頑張る話6:Hierarcyのオブジェクト名を一括置換する~

UI作業をしていると、いくつか似たよなオブジェクトを並べた際のリネームが手間になる事もある。
そんな時、選択したオブジェクトを同じ名前でリネームし、かつ、語尾に連番を入れてくれると助かると思った事が何度かある。
というわけで、作った。

using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

public class ObjectReplaceWindow : EditorWindow {
    private static ObjectReplaceWindow scene = null;
    // シーン一覧ウィンドウを表示する
    [UnityEditor.MenuItem("ShortCutCommand/OpenObjectReplaceWindow &2")]
    public static void OpenObjectReplaceWindow() {
        UnityEngine.Debug.Log("OpenObjectReplaceWindow");

        if (scene == null) {
            scene = EditorWindow.GetWindow<ObjectReplaceWindow>();
            scene.Show();
        } else {
            scene.Close();
            scene = null;
        }

        Debug.Log(Selection.gameObjects);
    }

    string replaceString = "";
    string replaceNumberKeyString = "";
    
    string replaceSameParentString = "";
    string replaceSameParentNumberKeyString = "";
    void OnGUI() {
        using (new EditorGUILayout.HorizontalScope()) {
            replaceString = EditorGUILayout.TextField(replaceString);
            replaceNumberKeyString = EditorGUILayout.TextField(replaceNumberKeyString);
        }
        if (GUILayout.Button("Replace")) {
            if (string.IsNullOrEmpty(replaceString)) {
            } else {
                if (string.IsNullOrEmpty(replaceNumberKeyString)) {
                    for (int i = 0; i < Selection.gameObjects.Length; i++) {
                        Selection.gameObjects[i].name = replaceString;
                    }
                } else {
                    for (int i = 0; i < Selection.gameObjects.Length; i++) {
                        Selection.gameObjects[i].name = string.Format("{0}{1}", replaceString, (int.Parse(replaceNumberKeyString) + i).ToString());
                    }
                }
            }
        }
        
        using (new EditorGUILayout.HorizontalScope()) {
            replaceSameParentString = EditorGUILayout.TextField(replaceSameParentString);
            replaceSameParentNumberKeyString = EditorGUILayout.TextField(replaceSameParentNumberKeyString);
        }
        
        if (GUILayout.Button("Replace")) {
            if (string.IsNullOrEmpty(replaceSameParentString)) {
            } else {
                if (string.IsNullOrEmpty(replaceSameParentNumberKeyString)) {
                    for (int i = 0; i < Selection.gameObjects.Length; i++) {
                        Selection.gameObjects[i].name = replaceSameParentString;
                    }
                } else {
                    int minSibIndex = 0;
                    for (int i = 0; i < Selection.gameObjects.Length; i++) {
                        int sibling = Selection.gameObjects[i].transform.GetSiblingIndex();
                        if (i == 0) {
                            minSibIndex = sibling;
                        }
                        if (sibling <= minSibIndex) {
                            minSibIndex = sibling;
                        }
                    }

                    for (int i = 0; i < Selection.gameObjects.Length; i++) {
                        int sibling = Selection.gameObjects[i].transform.GetSiblingIndex();
                        Selection.gameObjects[i].name = string.Format("{0}{1}", replaceSameParentString, (int.Parse(replaceSameParentNumberKeyString) + sibling-minSibIndex).ToString());// 0から開始したいため
                    }
                }
            }
        }
    }
}

使い方としては
・ウィンドウを開く
・Hierarcyウィンドウのオブジェクトを選択する
・1番目は、複数選択かつ別階層可能 ・ウィンドウの左側のインプットフィールドに、リネーム後の文字列を入れる
・連番にしたければ、右側のインプットフィールドに、始まりの数値を入れる
・Replaceを押す
・オブジェクトの生成日時が早い順に、置換文字列+連番のオブジェクト名にしてくれる
・数字を入れなければ、同じ文字列で置換される。これはこれで便利

・2番目は、複数選択かつ同階層限定 ・ウィンドウの左側のインプットフィールドに、リネーム後の文字列を入れる
・連番にしたければ、右側のインプットフィールドに、始まりの数値を入れる
・Replaceを押す
・オブジェクトの上から順、つまりSivling値順に、置換文字列+連番のオブジェクト名にしてくれる
・数字を入れなければ、同じ文字列で置換される。これはこれで便利

これだけ。