Unityエディタ拡張はじめました

個人的にはやや不調ですので、リハビリに手短に行かせていただきます。m(__)m

少しは役に立つかな? という小ネタを書いてみます。 

 

Unityのエディタ拡張

UnityのEditorは、スクリプトで機能を追加することが出来ます。

Assetsフォルダの下のどこかに"Editor"という名前のフォルダを作成し、エディタ用のスクリプトをその中に置けばOKです。

今回は下の内容の"PageView.cs"ファイルを置きました。 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;
using UnityEngine.SceneManagement;

// ページ切り替えを行うエディタ拡張
// メニューのEditor/PageViewerから呼び出します。
public class PageViewer : EditorWindow
{
    [MenuItem("Editor/MyPageViewer")]
    private static void Create()
    {
        // 生成
        GetWindow("MyPageViewer");
    }

    // MyPageViewerウィンドウが描画されるときの処理
    private void OnGUI()
    {
        // scene中のルートオブジェクトを全て取得
        Scene scene = SceneManager.GetActiveScene();
        GameObject[] rootObjects = scene.GetRootGameObjects();

        List pageObjects = new List();
        foreach (var rootObj in rootObjects)
        {
            // 子オブジェクトをすべて取得
            Transform[] childObjectsTransform = rootObj.GetComponentsInChildren(true);
            List childObjects = childObjectsTransform.Select(x => x.gameObject).ToList();
            // このうち、PageTagタグが付いているGameObjectを取得
            List taggedObjects = childObjects.Where(x => x.tag == "PageTop").ToList();
            // リストに追加
            pageObjects.AddRange(taggedObjects);
        }

        // PageTagタグが付いたGameObject一覧を表示
        foreach(GameObject pageObject in pageObjects)
        {
            // ボタンを表示
            if (GUILayout.Button(pageObject.name))
            {
                // ボタンが押された時の処理
                // ボタンに対応したpageObjectをアクティブに、それ以外のpageObjectを非アクティブにする
                pageObjects.ForEach(x => x.SetActive(x == pageObject));
            }
        }
    }
}

今回はUnityEditor.EditorWindowクラスを継承して、ウィンドウを作成しております。

関数に[MenuItem("Editor/MyPageViewer")]という属性をつけていますが、これにより"Editor"および"MyPageViewer"という名前の項目が追加され、これを選択した時にこの関数が呼び出されます。

f:id:chirotec:20180617003609p:plain

また、OnGUI()はウィンドウが描画されるたびに呼び出されます。

仕組みとしては昔のUnityのGUIに近く、GUILayout.Buttonなどの関数でGUIのボタンなどの部品を表示します。

f:id:chirotec:20180617003542p:plain

このスクリプトでは、シーン中のルートにあるオブジェクトより下の階層にあるゲームオブジェクトの中から、「"PageTop"」という名前のタグが付いたゲームオブジェクトを検索し、該当するオブジェクトの名前をボタンとして一覧表示しています。このボタンが押されたとき、ボタンに対応したオブジェクトがアクティブになり、その他のボタンに対応したオブジェクトが非アクティブ状態となります。

 

上記の画像の例では、「Page1」~「Page5」ボタンにPageTopタグを割り当てております。

「Page2」ボタンを押すと「Page2」がアクティブになり、その他の「Page1」などが非アクティブになります。

 

この例の検索の条件などを色々変えてみると、作業に役に立つ機能が作れるかもしれません。