その他
    ホーム 技術発信 DoRuby UnityEditor上で複数のゲームオブジェクトをプレハブ化する方法
    UnityEditor上で複数のゲームオブジェクトをプレハブ化する方法
     

    UnityEditor上で複数のゲームオブジェクトをプレハブ化する方法

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    はじめに

    Unityを使っていて、複数のゲームオブジェクトを同時にプレハブ化したい時がありました。Unityではひとつずつしかプレハブ化できないようになっています。それでは不便なのでどうにかできないか調べ、作ってみました。

    新しくウィンドウを作る

    では、新しくウィンドウを作ってみましょう。

    Assetsフォルダの中に、Editorと言う名のフォルダを作りましょう。基本的にエディタ拡張関連のスクリプトはこの中に保存しておきます。

    次に、そのEditorフォルダの中に新しくクラスを作りましょう。今回はExampleという名前のクラスを作ります。

    注意点として、新しくUnity上でウィンドウを開きたいときは、必ずEditorWindowクラスを継承しなければいけません。

    では、Openというメソッドを作り、そこにEditorWindow.GetWindow()と書きましょう。これで新しくウィンドウを作る準備は終わりました。ですが、実際に動かしてみると、どこにも表示させません。
    では次に、新しいウィンドウを表示させるために、それを表示させるメニューを作ります。
    下記のソースコードのように少し特殊な書き方になります。その下にあるopenメソッドは必ずstaticでなければなりません。
    またOnGUIの中にウィンドウ内のレイアウトなどを記述します。
    これでウィンドウが開けるようになりました。

    public class Example : EditorWindow {
        //メニューに項目追加
        [MenuItem("Example/新しくウィンドウを出します")]
        static void open() {
            EditorWindow.GetWindow<Example> ("Example");
        }
    
        void OnGUI() {
            EditorGUILayout.LabelField ("ようこそ");
        }
    }
    

    実行結果が以下のようになります。

    enter image description here

    複数プレハブ化

    では、複数プレハブ化するためにドラッグアンドドロップできるウィンドウを作りましょう。

    UnityがDragAndDropと言うUnityEditor上で行われるドラッグ&ドロップを操作するクラスを用意してくれているのでこれを使います。

    先ほど作ったOnGUIメソッドの中にソースコードを書き足していきます。
    まず、ドロップするエリアを追加するコードを書きます。
    Event.currentで現在のUnityが処理中のEventが取れます。
    そのEventがドロップエリア内でドロップしているなら、DragAndDrop.objectReferencesでドラッグしているオブジェクトすべてをプレハブ化する処理になっています。
    OnGUIの中に、以下のソースコードを書きます。

    private string saveFolderPath = "Assets/Prefab/";
    
    void OnGUI() {
        var dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
        GUI.Box(dropArea, "drop");
        var evt = Event.current;
    
        switch(evt.type) {
            case EventType.DragPerform:
                if(!dropArea.Contains(evt.mousePosition)) break;
                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
                DragAndDrop.AcceptDrag();
                break;
    
            case EventType.DragExited:
                foreach(GameObject go in DragAndDrop.objectReferences) {
                    Debug.Log(go);
                    DropList.Add(go);
                }
    
                CreatePrefabs();
                Event.current.Use();
                break;
        }
    }
    
    //プレハブ化する関数
    void CreatePrefabs() {
        foreach(GameObject go in DropList) {
            if(DropList == null) {
                return;
            }
            string prefab = saveFolderPath + go.name +".prefab";
            if(go.GetComponent<Image>() != null) {
                CreatePrefabImage(prefab, go);
            } else {
                PrefabUtility.CreatePrefab(prefab, go);
            }
        }
        DropList.Clear();
    }
    
    

    まとめ

    今回は、複数のオブジェクトをプレハブ化する機能を実装しましたが、このエディタ拡張を使えば、自分の好きなようにカスタマイズすることができるようになります。
    そうやって、Unityを自分好みに染めていってください

    今回この機能を作るにあたっていくつか参考にさせていただいたサイトのリンクを載せておきます。
    【エディタ拡張徹底解説】初級編①:ウィンドウを自作してみよう【Unity】
    エディター拡張入門