けいごのなんとか

Unityユーザーとしてのブログ。ギリギリ路線走ってます。

UnityEngine.ObjectのCustomEditorを作成する

前提知識

Unityがサポートしていない拡張子のアセットは全てUnityEngine.Objectとして扱われます

UnityEngine.ObjectのCustomEditorを作成したい

すべてUnityEngine.Objectとして扱われるので少し工夫が必要ですが、以下の点を抑えておけば大丈夫です

  • CustomEditorは1つのオブジェクトに対し必ず1つ (ただし、editorForChildClassesが有効な場合は除く)
  • 様々なCustomEditorを使用したい場合は、Editor.CreateEditorを使用する

サンプルとして、ZipとFolderのCustomEditorを作成しました。 機能としてはHierarchyが表示されるようになっています

ObjectEditor

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;

[CustomEditor(typeof(Object))]
public class ObjectEditor : Editor
{
        static Editor editor;

        static string extension {
                get {
                        return Path.GetExtension (AssetDatabase.GetAssetPath (Selection.activeObject));
                }
        }

        public ObjectEditor ()
        {
                if (extension == ".zip") {
                        editor = Editor.CreateEditor (Selection.activeObject, typeof(ZipEditor));
                } else if (string.IsNullOrEmpty (extension)) {
                        editor = Editor.CreateEditor (Selection.activeObject, typeof(FolderEditor));
                } else {
                        editor = null;
                }
        }

        public override void OnInspectorGUI ()
        {
                if (editor != null)
                        editor.OnInspectorGUI ();
        }

        public override void OnPreviewGUI (Rect r, GUIStyle background)
        {
                if (editor != null)
                        editor.OnPreviewGUI (r, background);
        }
}

zip

f:id:anchan828:20130624023912p:plain

using UnityEditor;
using UnityEngine;
using Ionic.Zip;
using System.IO;

public class ZipEditor : Editor
{                   
        ZipFile zip;

        string GetCurrentDirectory (string path)
        {
                return new DirectoryInfo (path).Name;
        }

        public ZipEditor ()
        {
                Unzip ();
        }

        void Unzip ()
        {
                if (Selection.activeObject != null)
                        zip = ZipFile.Read (AssetDatabase.GetAssetPath (Selection.activeObject));
        }

        public override void OnInspectorGUI ()
        {
                EditorGUIUtility.SetIconSize (Vector2.one * 16);
                if (zip == null)
                        return;
                Draw ();
        }

        void Draw ()
        {
                EditorGUILayout.LabelField (GetCurrentDirectory(zip.Name));
                foreach (var entry in zip) {
                        EditorGUI.indentLevel = entry.FileName.Split (Path.DirectorySeparatorChar).Length;
                        if (entry.IsDirectory) {
                                EditorGUILayout.LabelField (GetCurrentDirectory(entry.FileName));
                        } else {
                                EditorGUI.indentLevel ++;
                                EditorGUILayout.LabelField (Path.GetFileName(entry.FileName));
                        }
                }   
        }
}

folder

f:id:anchan828:20130624023905p:plain

using UnityEngine;
using UnityEditor;
using System.IO;

public class FolderEditor : Editor
{
        public override void OnInspectorGUI ()
        {
                EditorGUIUtility.SetIconSize (Vector2.one * 16);
                string currentPath = AssetDatabase.GetAssetPath (Selection.activeObject);
                DrawFiles (currentPath, 0);
        }

        static void DrawFiles (string currentPath, int indent)
        {
                EditorGUI.indentLevel = indent;
                EditorGUILayout.LabelField (GetGUIContent (currentPath));
                foreach (var path in Directory.GetFiles(currentPath)) {
                        EditorGUI.indentLevel = indent + 1;
                        EditorGUILayout.LabelField (GetGUIContent (path));
                }
        
                foreach (var path in Directory.GetDirectories(currentPath)) {
                        DrawFiles (path, indent + 1);
                }
        }

        static GUIContent GetGUIContent (string path)
        {
                Object asset = AssetDatabase.LoadAssetAtPath (path, typeof(Object));  
                GUIContent content = EditorGUIUtility.ObjectContent (asset, asset.GetType ());
                content.image = AssetDatabase.GetCachedIcon (path);
                return content;
        }
}