SlideShare a Scribd company logo
1 of 30
Download to read offline
Extending the Unity Editor
                    Unity Editor の 拡張について
Extending the Unity Editor
 まずはUnityのGUIを理解しよう (1/2)
 ・基本的にデバッグ用
    毎フレーム1つ1つのコンポーネントについて判定・再描画が
    行われるので重い。また使いこなすにはGUISkinなどの細かい
    仕様を覚えなくてはならず面倒。

 ・Viewport空間ではなくScreen空間に描画
    スクリーンに対する絶対座標で描画されるので、画面解像度が
    変わった時に破綻する。

 ・フォントの問題
    PC/Mac以外で日本語文字を表示しようとすると非常に面倒。
    携帯機ではDynamicフォントが使えない。

                                 2/30
Extending the Unity Editor
 まずはUnityのGUIを理解しよう (2/2)
 ・OnGUI()に表示と処理を一緒くたに書く
    ゲーム実行中に、ゲームオブジェクトの更新と描画が終わった
    タイミングでOnGUI()が呼ばれ、そこに記述されている内容が
    実行される。
     void OnGUI()
     {
          if (GUILayout.Button("Next Level"))
          {
               Application.LoadLevel("Level2");
          }
          if (GUILayout.Button("Quit"))
          {
               Application.Quit();
          }
     }



 ・拡張エディタの場合もこの辺の仕組みは同じ
    インスペクタやウィンドウの再描画が必要なタイミングで、
    OnInspectorGUI()やOnGUI()が呼ばれる。
                                                  3/30
Extending the Unity Editor
 GUIとGUILayout (1/2)
 ・GUI = 自由配置
    第一引数が必ず、位置とサイズを指定するためのRect構造体。
     void OnGUI()
     {
          GUI.Button(new Rect(10,   10, 100, 50),   "Button1");
          GUI.Button(new Rect(50,   50, 100, 50),   "Button2");
          GUI.Button(new Rect(90,   90, 100, 50),   "Button3");
          text = GUI.TextArea(new   Rect(200, 10,   100, 100), text);
     }




                                                                        4/30
Extending the Unity Editor
 GUIとGUILayout (2/2)
 ・GUILayout = 逐次配置
    書いていった順に並んで表示される。BeginHorizontalなどで
    グループ化して並べることも可能。
     void OnGUI()
     {
          GUILayout.BeginHorizontal(); //水平方向にグループ化
               GUILayout.BeginVertical();        //垂直方向にグループ化
                    GUILayout.Button("Button1");
                    GUILayout.Button("Button2");
                    GUILayout.Button("Button3");
               GUILayout.EndVertical();
               text = GUILayout.TextArea(text, GUILayout.Width(200), GUILayout.Height(60));
          GUILayout.EndHorizontal();
     }

                                                                ※インデントは気分。必須ではない。




                                                                                              5/30
Extending the Unity Editor
 EditorGUIとEditorGUILayout (1/2)
 ・GUI・GUILayoutの関係と同じ
    EditorGUIは絶対座標指定、EditorGUILayoutは逐次配置。
    Editor向けに便利なパーツが用意されている。

 ・GUI系とEditorGUI系は混在可能
    というよりEditorGUIにはButton等の基本的なパーツはなく、
    GUI系と混在させて使うことが前提。
     public override void OnInspectorGUI()
     {
          GUILayout.BeginHorizontal();
          position = EditorGUILayout.Vector3Field("Position", position);
          if (GUILayout.Button("Reset"))
               position = Vector3.zero;
          GUILayout.EndHorizontal();
     }




                                                                           6/30
Extending the Unity Editor
 EditorGUIとEditorGUILayout (2/2)
 ・基本的にEditorGUILayoutを使用
    ゲーム用のGUIがゲーム画面の左上を基準にして配置されるよ
    うに、エディタ用のGUIはインスペクタやウィンドウの左上を
    基準にして配置されていく。
    座標を全部自前で計算してもいいが、EditorGUILayoutで配置
    しておくとスケーリングが自動で行われるのでスマート。

 ・位置調整用のパーツもある
    領域のサイズを考慮して自動的に伸縮するFlexibleSpace()や
    逆に勝手に伸縮しないようにするGUILayout.ExpandWidth()
    を上手く使ってかっこ良く配置しよう。



                                        7/30
Extending the Unity Editor
 インスペクタを拡張してみよう (1/5)
 ・何を拡張できるの?
    インスペクタに表示されるものなら何でも。
    選択中のオブジェクトに対する操作やインスペクタでの表示の
    され方を独自に記述可能。

 ・コンポーネントごとに拡張クラスを定義
    拡張インスペクタはインスペクタ全体ではなくTransformとか
    Cameraとかの各コンポーネント毎にクラスを定義していく。
     using UnityEngine; // 必須
     using UnityEditor; // 必須

     [CustomEditor(typeof(Transform))] // Transformクラス用の拡張であることを表すアトリビュート
     public sealed class CustomTransformEditor : Editor // Editorクラスを継承する
     {
          public override void OnInspectorGUI() // インスペクタが再描画されるタイミングで呼ばれる
          {
               ...


                                                                             8/30
Extending the Unity Editor
 インスペクタを拡張してみよう (2/5)
 ・どう拡張できるの?
    例えば左のようなプロパティを持つコンポーネントを作ったと
    する。するとインスペクタでの表示は右のようになる。
     using UnityEngine;

     public class Hoge : MonoBehaviour
     {
          public Vector3 velocity;
     }



    これではVectorの各要素が縦に並んでいて非常に無様である。
    しかも初期状態では折りたたまれているし、色々ひどい。
    これをTransformの表示のように横に並べたい。


                                         すっきり!
                                                 9/30
Extending the Unity Editor
 インスペクタを拡張してみよう (3/5)
 ・拡張エディタクラスを定義する
    エディタのProject直下(フォルダ構成としてはAssets直下)に
    Editorという名前のフォルダを作り、そこに新規スクリプトを
    配置。MonoBehaviour向けに書かれている内容をEditor向け
    に書きなおす。
                      using UnityEngine; // 必須
                      using UnityEditor; // 必須

                      [CustomEditor(typeof(Hoge))] // Hogeクラス用の拡張であることを宣言
                      public sealed class HogeEditor : Editor
                      {
                           public override void OnInspectorGUI()
                           {
                                DrawDefaultInspector(); // とりあえずデフォルトの表示
                           }
                      }




                                                                      10/30
Extending the Unity Editor
 インスペクタを拡張してみよう (4/5)
 ・拡張エディタクラスを実装する
    EditorGUILayoutには、そのものズバリVector3Fieldという
    パーツが用意されているのでそれを利用。
     using UnityEngine;
     using UnityEditor;

     [CustomEditor(typeof(Hoge))]
     public sealed class HogeEditor : Editor
     {
          public override void OnInspectorGUI()
          {
               // 今インスペクタで表示しているオブジェクトのインスタンスがtargetに格納されている
               Hoge hoge = target as Hoge; // targetプロパティはObject型なので目的の型にキャスト
               Vector3 v = EditorGUILayout.Vector3Field("Velocity", hoge.velocity);
               if (v != hoge.velocity) // 変更があった場合のみ処理する
               {
                    Undo.RegisterUndo(hoge, "Velocity Change"); // アンドゥバッファに登録
                    hoge.velocity = v;
                    EditorUtility.SetDirty(target); // アセットデータベースに変更を通知
               }
          }
     }




                                                                                      11/30
Extending the Unity Editor
 インスペクタを拡張してみよう (5/5)
 ・拡張エディタクラスを堪能する
    Unityにフォーカスを戻してコンパイルエラーなどがなければ、
    インスペクタの表示が以下のように変化している。

                              Undo.RegisterUndo()して
                              あるので、Ctrl+Zで取り消し、
                              Ctrl+Yでやり直しもバッチリ。




                                                12/30
Extending the Unity Editor
 もっと拡張してみよう (1/2)
 ・リセット・コピー&ペーストの実装
    先ほどのプロパティをゼロリセットするボタンと、数値を別の
    オブジェクトにコピー&ペーストするボタンを付けてみる。
       static Vector3 copyBuffer = Vector3.zero;
       public override void OnInspectorGUI()
       {
            Hoge hoge = target as Hoge;
            Vector3 v = EditorGUILayout.Vector3Field("Velocity", hoge.velocity);
            EditorGUILayout.BeginHorizontal(); // 水平方向に並べる
            if (GUILayout.Button("Reset", EditorStyles.miniButton)) // 見た目にこだわってみる
                 v = Vector3.zero;
            GUILayout.Space(GUILayoutUtility.GetAspectRect(1).width / 3);
            if (GUILayout.Button("Copy", EditorStyles.miniButtonLeft))
                 copyBuffer = v;
            if (GUILayout.Button("Paste", EditorStyles.miniButtonRight))
                 v = copyBuffer;
            EditorGUILayout.EndHorizontal();
            if (v != hoge.velocity)
            {
                 Undo.RegisterUndo(hoge, "Velocity Change");
                 hoge.velocity = v;
                 EditorUtility.SetDirty(target);
            }
       }


                                                                                     13/30
Extending the Unity Editor
 もっと拡張してみよう (2/2)
 ・挙動の確認
    Unityにフォーカスを戻してコンパイルエラーなどがなければ、
    インスペクタの表示が以下のように変化している。

                              EditorStylesの指定や空白を
                              配置したことで、まとまりの
                              ある見た目にする事ができた。




                                              14/30
Extending the Unity Editor
 他にもこんな便利なパーツが
 ・範囲指定
    EditorGUILayout.MinMaxSlider()




 ・ゲージ表示
    EditorGUI.ProgressBar()




                                     15/30
Extending the Unity Editor
 拡張インスペクタの振る舞い (1/2)
 ・必要な時にnewされている
    先ほど実装した拡張インスペクタは、Unityエディタ上で対象の
    コンポーネントがアタッチされているオブジェクトが選択され
    る度にnewされている。

    従って、1つのオブジェクトを選択している間はインスペクタ
    自体のメンバプロパティは保持されるが、別のオブジェクトを
    選択するとインスペクタのメンバは初期値に戻る。

    複数オブジェクトをまたいでやりとりしたい情報がある場合は
    staticメンバを利用しよう。

    またOnEnable()をオーバーライドすることで、オブジェクト
    を選択した瞬間の挙動を定義することも可能。
                                  16/30
Extending the Unity Editor
 拡張インスペクタの振る舞い (2/2)
 ・必要な時にOnInspectorGUI()が呼ばれる
    OnGUI()が毎フレーム呼ばれるのと違い、OnInspectorGUI()
    はインスペクターペインの再描画が必要になったタイミングで
    随時呼ばれている。

    従って「一定間隔で明滅する」といったような、エディタ上で
    リアルタイムに何かを動かすような処理は基本的にできない。
    (毎回Repaint()を呼びまくれば可能ではある)

 ・シーンビューの更新時にはOnSceneGUI()
    インスペクタの親クラスであるEditorにはOnSceneGUI()と
    いうメソッドもあり、これはシーンビューが更新されるときに
    呼ばれている。どう使うのかというと…
                                       17/30
Extending the Unity Editor
 シーンビューも拡張してみよう (1/3)
 ・ハンドル(マニピュレータ)の表示
    ベクトルを下図のようにグラフィカルに表示したい。




                               18/30
Extending the Unity Editor
 シーンビューも拡張してみよう (2/3)
 ・ハンドル(マニピュレータ)の表示
    拡張インスペクタで取り扱っている情報を、シーンビュー上に
    グラフィカルに表示すると理解しやすくなる場合がある。
     [CustomEditor(typeof(Hoge))]
     public sealed class HogeEditor : Editor
     {
          Hoge hoge = null;
          void OnEnable()
          {
               hoge = target as Hoge;
          }
          void OnSceneGUI()
          {
               Vector3 root = hoge.transform.position; // 起点を計算
               Vector3 cap = root + hoge.velocity;     // 終点を計算
               Handles.color = Color.magenta;          // 色を変更
               Handles.DrawLine(root, cap);            // 線を描画
               Quaternion rot = Quaternion.LookRotation(hoge.velocity); // 終点の向きを計算
               float size = HandleUtility.GetHandleSize(cap); // カメラ距離に依らないサイズを計算
               Handles.ArrowCap(0, cap, rot, size);    // 矢印型の終点を描画
          }
          static Vector3 copyBuffer = Vector3.zero;
          public override void OnInspectorGUI()


                                                                                      19/30
Extending the Unity Editor
 シーンビューも拡張してみよう (3/3)
 ・ハンドル(マニピュレータ)の表示
    ベクトルがグラフィカルに表示されるようになった。




                               20/30
Extending the Unity Editor
 拡張インスペクタの例




                             21/30
Extending the Unity Editor
 ウィンドウを作ってみよう (1/5)
 ・何を拡張できるの?
    Build Settingのようなフローティングウィンドウや、
    AnimationウィンドウのようなDock可能なウィンドウ、
    あるいは簡単なウィザードなどを独自に作ることができる。

 ・ウィンドウごとに拡張クラスを定義
    カスタムウィンドウは拡張インスペクタと違い、ウィンドウ
    1つ1つが独立したインスタンスとして振舞う。
     using UnityEngine; // 必須
     using UnityEditor; // 必須

     public sealed class MaterialReplacer : EditorWindow // EditorWindowクラスを継承する
     {
          [MenuItem("Tool/Replace Material...")] // エディタのメニューに項目が追加される
          static void OpenWindow()               // 上記項目をクリックするとこの関数が呼ばれる
          {



                                                                                   22/30
Extending the Unity Editor
 ウィンドウを作ってみよう (2/5)
 ・Floatingウィンドウの場合
     public sealed class MaterialReplacer : EditorWindow
     {
          [MenuItem("Tool/Replace Material...")]
          static void OpenWindow() // メニューから呼ばれるためにはstatic関数でなければならない
          {
               EditorWindow.GetWindow<MaterialReplacer>(true, "Replace Material");
          }
     }




                                                                                     23/30
Extending the Unity Editor
 ウィンドウを作ってみよう (3/5)
 ・Dockableウィンドウの場合
     public sealed class MaterialReplacer : EditorWindow
     {
          [MenuItem("Tool/Replace Material...")]
          static void OpenWindow() // メニューから呼ばれるためにはstatic関数でなければならない
          {
               EditorWindow.GetWindow<MaterialReplacer>(false, "Replace Material");
          }
     }




                                                                        Dock可能


                                                                                      24/30
Extending the Unity Editor
 ウィンドウを作ってみよう (4/5)
 ・OnGUI()にレイアウトを実装
    拡張インスペクタと同じ要領で、OnGUI()をオーバーライドし
    そこへレイアウトを入れこんでいく。
       [MenuItem("Tool/Replace Material...")]
       static void OpenWindow()
       {
            EditorWindow.GetWindow<MaterialReplacer>(false, "Replace Material");
       }
       static Material targetMaterial = null;
       void OnGUI()
       {
            targetMaterial = EditorGUILayout.ObjectField(
                 "Material", targetMaterial, typeof(Material), false
            ) as Material;
            GUI.enabled = (targetMaterial != null) && (Selection.gameObjects.Length > 0);
            if (GUILayout.Button("Replace!"))
            {
                 foreach (var renderer in from go in Selection.gameObjects select go.renderer)
                      if (renderer != null)
                           renderer.sharedMaterial = targetMaterial;
            }
            GUI.enabled = true;
       }



                                                                                         25/30
Extending the Unity Editor
 ウィンドウを作ってみよう (5/5)
 ・ウィンドウが完成
    選択中のゲームオブジェクト全てのマテリアルを、指定した
    ものに差し替えるツールが完成。




        マテリアルを選択し、差し替え
        たいオブジェクトを選択状態に
        したらReplaceボタンを押す
                             選択中のオブジェクトにレンダラが付い
                             ていれば、そのマテリアルが差し替わる


                                             26/30
Extending the Unity Editor
 覚えておきたい (1/4)
 ・Selectionクラス
    エディタ上で選択中のオブジェクトには、Selectionクラスを
    通してアクセスできる。




                                  27/30
Extending the Unity Editor
 覚えておきたい (2/4)
 ・Undoクラス
    スクリプトから変更した情報は、何もしないとUndoの履歴に
    残らない。エディタの拡張をする場合はUndo.RegisterUndo
    を有効に使い、ユーザーの利便性を図ろう。




                                    28/30
Extending the Unity Editor
 覚えておきたい (3/4)
 ・EditorUtility、FileUtilなどのユーティリティ
    EditorUtilityにはファイルオープンダイアログやYes/No形式
    のダイアログを表示するためのメソッド、FileUtilにはファイル
    のコピーや削除などを行うメソッドなど、色々便利なインター
    フェースが用意されている。

 ・スクリプトから全ての設定にアクセス可能
    PlayerSettingsやEditorUserBuildSettingsなどを通して、
    エディタ上で触れる設定項目は全てスクリプトからも操作が
    可能。面倒な処理はバッチ化してしまえ。




                                              29/30
Extending the Unity Editor
 覚えておきたい (4/4)
 ・ファイル出力やシステムコールも可能
    System.IO.StreamWriterを使ってgmcs.rspを書きだしたり
    System.Diagnostics.Processを使ってシステムコールを
    呼び出すことも可能。Unity組み込みのWWWクラスを使って
    簡単にウェブサーバと連携したり、可能性は無限大。




                                          30/30

More Related Content

What's hot

徹底解説!UE4を使ったモバイルゲーム開発におけるコンテンツアップデートの極意!
徹底解説!UE4を使ったモバイルゲーム開発におけるコンテンツアップデートの極意!徹底解説!UE4を使ったモバイルゲーム開発におけるコンテンツアップデートの極意!
徹底解説!UE4を使ったモバイルゲーム開発におけるコンテンツアップデートの極意!エピック・ゲームズ・ジャパン Epic Games Japan
 
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しようUnityTechnologiesJapan002
 
IncrediBuildでビルド時間を最大90%短縮! - インクレディビルドジャパン株式会社 - GTMF 2018 OSAKA
IncrediBuildでビルド時間を最大90%短縮! - インクレディビルドジャパン株式会社 - GTMF 2018 OSAKAIncrediBuildでビルド時間を最大90%短縮! - インクレディビルドジャパン株式会社 - GTMF 2018 OSAKA
IncrediBuildでビルド時間を最大90%短縮! - インクレディビルドジャパン株式会社 - GTMF 2018 OSAKAGame Tools & Middleware Forum
 
UnrealBuildTool勉強会まとめ
UnrealBuildTool勉強会まとめUnrealBuildTool勉強会まとめ
UnrealBuildTool勉強会まとめShun Sasaki
 
UE4 アセットロード周り-アセット参照調査-
UE4 アセットロード周り-アセット参照調査-UE4 アセットロード周り-アセット参照調査-
UE4 アセットロード周り-アセット参照調査-com044
 
出張ヒストリア ブループリントを書くにあたって大切なこと
出張ヒストリア ブループリントを書くにあたって大切なこと出張ヒストリア ブループリントを書くにあたって大切なこと
出張ヒストリア ブループリントを書くにあたって大切なことhistoria_Inc
 
[IGF2018] UE4でAndroidアプリを開発する際に知っておきたいパフォーマンス改善テクニック + INDIE GAMES FESTIVAL 2...
[IGF2018] UE4でAndroidアプリを開発する際に知っておきたいパフォーマンス改善テクニック + INDIE GAMES FESTIVAL 2...[IGF2018] UE4でAndroidアプリを開発する際に知っておきたいパフォーマンス改善テクニック + INDIE GAMES FESTIVAL 2...
[IGF2018] UE4でAndroidアプリを開発する際に知っておきたいパフォーマンス改善テクニック + INDIE GAMES FESTIVAL 2...エピック・ゲームズ・ジャパン Epic Games Japan
 
【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~
【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~
【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~UnityTechnologiesJapan002
 
UE4におけるキャラクタークラス設計
UE4におけるキャラクタークラス設計UE4におけるキャラクタークラス設計
UE4におけるキャラクタークラス設計Masahiko Nakamura
 

What's hot (20)

徹底解説!UE4を使ったモバイルゲーム開発におけるコンテンツアップデートの極意!
徹底解説!UE4を使ったモバイルゲーム開発におけるコンテンツアップデートの極意!徹底解説!UE4を使ったモバイルゲーム開発におけるコンテンツアップデートの極意!
徹底解説!UE4を使ったモバイルゲーム開発におけるコンテンツアップデートの極意!
 
なぜなにFProperty - 対応方法と改善点 -
なぜなにFProperty - 対応方法と改善点 -なぜなにFProperty - 対応方法と改善点 -
なぜなにFProperty - 対応方法と改善点 -
 
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
 
IncrediBuildでビルド時間を最大90%短縮! - インクレディビルドジャパン株式会社 - GTMF 2018 OSAKA
IncrediBuildでビルド時間を最大90%短縮! - インクレディビルドジャパン株式会社 - GTMF 2018 OSAKAIncrediBuildでビルド時間を最大90%短縮! - インクレディビルドジャパン株式会社 - GTMF 2018 OSAKA
IncrediBuildでビルド時間を最大90%短縮! - インクレディビルドジャパン株式会社 - GTMF 2018 OSAKA
 
UE4で作成するUIと最適化手法
UE4で作成するUIと最適化手法UE4で作成するUIと最適化手法
UE4で作成するUIと最適化手法
 
UE4のモバイル開発におけるコンテンツアップデートの話 - Chunk IDとの激闘編 -
UE4のモバイル開発におけるコンテンツアップデートの話 - Chunk IDとの激闘編 -UE4のモバイル開発におけるコンテンツアップデートの話 - Chunk IDとの激闘編 -
UE4のモバイル開発におけるコンテンツアップデートの話 - Chunk IDとの激闘編 -
 
UnrealBuildTool勉強会まとめ
UnrealBuildTool勉強会まとめUnrealBuildTool勉強会まとめ
UnrealBuildTool勉強会まとめ
 
UE4 アセットロード周り-アセット参照調査-
UE4 アセットロード周り-アセット参照調査-UE4 アセットロード周り-アセット参照調査-
UE4 アセットロード周り-アセット参照調査-
 
[CEDEC2018] UE4アニメーションシステム総おさらい
[CEDEC2018] UE4アニメーションシステム総おさらい[CEDEC2018] UE4アニメーションシステム総おさらい
[CEDEC2018] UE4アニメーションシステム総おさらい
 
出張ヒストリア ブループリントを書くにあたって大切なこと
出張ヒストリア ブループリントを書くにあたって大切なこと出張ヒストリア ブループリントを書くにあたって大切なこと
出張ヒストリア ブループリントを書くにあたって大切なこと
 
UE4を用いたTPS制作事例 EDF:IR パラメータ管理実装実例
UE4を用いたTPS制作事例 EDF:IR パラメータ管理実装実例UE4を用いたTPS制作事例 EDF:IR パラメータ管理実装実例
UE4を用いたTPS制作事例 EDF:IR パラメータ管理実装実例
 
Visual Dataprepで建築データを美味しく下ごしらえ UNREAL FEST EXTREME 2021 SUMMER
Visual Dataprepで建築データを美味しく下ごしらえ UNREAL FEST EXTREME 2021 SUMMERVisual Dataprepで建築データを美味しく下ごしらえ UNREAL FEST EXTREME 2021 SUMMER
Visual Dataprepで建築データを美味しく下ごしらえ UNREAL FEST EXTREME 2021 SUMMER
 
[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)
[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)
[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)
 
アーティストの為のプロファイル入門!~楽しいRenderDocの使い方~
アーティストの為のプロファイル入門!~楽しいRenderDocの使い方~アーティストの為のプロファイル入門!~楽しいRenderDocの使い方~
アーティストの為のプロファイル入門!~楽しいRenderDocの使い方~
 
[IGF2018] UE4でAndroidアプリを開発する際に知っておきたいパフォーマンス改善テクニック + INDIE GAMES FESTIVAL 2...
[IGF2018] UE4でAndroidアプリを開発する際に知っておきたいパフォーマンス改善テクニック + INDIE GAMES FESTIVAL 2...[IGF2018] UE4でAndroidアプリを開発する際に知っておきたいパフォーマンス改善テクニック + INDIE GAMES FESTIVAL 2...
[IGF2018] UE4でAndroidアプリを開発する際に知っておきたいパフォーマンス改善テクニック + INDIE GAMES FESTIVAL 2...
 
UE4のモバイル向け機能や最新情報などを改めて紹介!2019
UE4のモバイル向け機能や最新情報などを改めて紹介!2019UE4のモバイル向け機能や最新情報などを改めて紹介!2019
UE4のモバイル向け機能や最新情報などを改めて紹介!2019
 
【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~
【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~
【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~
 
UE4におけるキャラクタークラス設計
UE4におけるキャラクタークラス設計UE4におけるキャラクタークラス設計
UE4におけるキャラクタークラス設計
 
[4.20版] UE4におけるLoadingとGCのProfilingと最適化手法
[4.20版] UE4におけるLoadingとGCのProfilingと最適化手法[4.20版] UE4におけるLoadingとGCのProfilingと最適化手法
[4.20版] UE4におけるLoadingとGCのProfilingと最適化手法
 
Fortniteを支える技術
Fortniteを支える技術Fortniteを支える技術
Fortniteを支える技術
 

Similar to Extending the Unity Editor

Extending the Unity Editor Extended
Extending the Unity Editor ExtendedExtending the Unity Editor Extended
Extending the Unity Editor ExtendedMasamitsu Ishikawa
 
ゲームツクール!第11回 エディター拡張してみよう
ゲームツクール!第11回 エディター拡張してみようゲームツクール!第11回 エディター拡張してみよう
ゲームツクール!第11回 エディター拡張してみようゲームツクール!
 
iOSのUI構築小技集(小さなとこから始められる編)
iOSのUI構築小技集(小さなとこから始められる編)iOSのUI構築小技集(小さなとこから始められる編)
iOSのUI構築小技集(小さなとこから始められる編)Fumiya Sakai
 
ARコンテンツ作成勉強会:Myoを用いたVRコンテンツ開発
ARコンテンツ作成勉強会:Myoを用いたVRコンテンツ開発ARコンテンツ作成勉強会:Myoを用いたVRコンテンツ開発
ARコンテンツ作成勉強会:Myoを用いたVRコンテンツ開発Takashi Yoshinaga
 
Unity勉強会ハンズオン
Unity勉強会ハンズオンUnity勉強会ハンズオン
Unity勉強会ハンズオンKodai Yano
 
Unityの夕べ in Fukuoka
Unityの夕べ in FukuokaUnityの夕べ in Fukuoka
Unityの夕べ in FukuokaShinobu Izumi
 
Editor スクリプティング 入門
Editor スクリプティング 入門Editor スクリプティング 入門
Editor スクリプティング 入門Keigo Ando
 
【Unite 2018 Tokyo】エディター拡張マニアクス2018
【Unite 2018 Tokyo】エディター拡張マニアクス2018【Unite 2018 Tokyo】エディター拡張マニアクス2018
【Unite 2018 Tokyo】エディター拡張マニアクス2018Unity Technologies Japan K.K.
 
Pin-point rebuildable and non-rebuild custom widget
Pin-point rebuildable and non-rebuild custom widgetPin-point rebuildable and non-rebuild custom widget
Pin-point rebuildable and non-rebuild custom widgetcch-robo
 
HoloLensハンズオン:AirTap & SpatialMapping編
HoloLensハンズオン:AirTap & SpatialMapping編HoloLensハンズオン:AirTap & SpatialMapping編
HoloLensハンズオン:AirTap & SpatialMapping編Takashi Yoshinaga
 
OSC2011 Androidハンズオン
OSC2011 AndroidハンズオンOSC2011 Androidハンズオン
OSC2011 AndroidハンズオンKatsumi Honda
 
第10回ゲームツクール uGUIをアニメーションさせよう
第10回ゲームツクール uGUIをアニメーションさせよう第10回ゲームツクール uGUIをアニメーションさせよう
第10回ゲームツクール uGUIをアニメーションさせようゲームツクール!
 
Flutter のリアクティブ戦略 set state 〜 redux まで
Flutter のリアクティブ戦略 set state 〜 redux までFlutter のリアクティブ戦略 set state 〜 redux まで
Flutter のリアクティブ戦略 set state 〜 redux までcch-robo
 
2015年度研究室プレ卒研用Android講座2
2015年度研究室プレ卒研用Android講座22015年度研究室プレ卒研用Android講座2
2015年度研究室プレ卒研用Android講座2Hokuto Tateyama
 
FlutterをRenderObjectまで理解する
FlutterをRenderObjectまで理解するFlutterをRenderObjectまで理解する
FlutterをRenderObjectまで理解するKeisukeKiriyama
 
デザイナーとエンジニアが話す、iOSアプリケーション開発
デザイナーとエンジニアが話す、iOSアプリケーション開発デザイナーとエンジニアが話す、iOSアプリケーション開発
デザイナーとエンジニアが話す、iOSアプリケーション開発Kenta Ohsugi
 
試して感覚を掴んでみるUICollectionViewCompositionalLayout & Combine
試して感覚を掴んでみるUICollectionViewCompositionalLayout & Combine試して感覚を掴んでみるUICollectionViewCompositionalLayout & Combine
試して感覚を掴んでみるUICollectionViewCompositionalLayout & CombineFumiya Sakai
 

Similar to Extending the Unity Editor (20)

Extending the Unity Editor Extended
Extending the Unity Editor ExtendedExtending the Unity Editor Extended
Extending the Unity Editor Extended
 
ゲームツクール!第11回 エディター拡張してみよう
ゲームツクール!第11回 エディター拡張してみようゲームツクール!第11回 エディター拡張してみよう
ゲームツクール!第11回 エディター拡張してみよう
 
iOSのUI構築小技集(小さなとこから始められる編)
iOSのUI構築小技集(小さなとこから始められる編)iOSのUI構築小技集(小さなとこから始められる編)
iOSのUI構築小技集(小さなとこから始められる編)
 
ARコンテンツ作成勉強会:Myoを用いたVRコンテンツ開発
ARコンテンツ作成勉強会:Myoを用いたVRコンテンツ開発ARコンテンツ作成勉強会:Myoを用いたVRコンテンツ開発
ARコンテンツ作成勉強会:Myoを用いたVRコンテンツ開発
 
Unity勉強会ハンズオン
Unity勉強会ハンズオンUnity勉強会ハンズオン
Unity勉強会ハンズオン
 
Unityの夕べ in Fukuoka
Unityの夕べ in FukuokaUnityの夕べ in Fukuoka
Unityの夕べ in Fukuoka
 
Editor スクリプティング 入門
Editor スクリプティング 入門Editor スクリプティング 入門
Editor スクリプティング 入門
 
Flashup 8
Flashup 8Flashup 8
Flashup 8
 
【Unite 2018 Tokyo】エディター拡張マニアクス2018
【Unite 2018 Tokyo】エディター拡張マニアクス2018【Unite 2018 Tokyo】エディター拡張マニアクス2018
【Unite 2018 Tokyo】エディター拡張マニアクス2018
 
Pin-point rebuildable and non-rebuild custom widget
Pin-point rebuildable and non-rebuild custom widgetPin-point rebuildable and non-rebuild custom widget
Pin-point rebuildable and non-rebuild custom widget
 
HoloLensハンズオン:AirTap & SpatialMapping編
HoloLensハンズオン:AirTap & SpatialMapping編HoloLensハンズオン:AirTap & SpatialMapping編
HoloLensハンズオン:AirTap & SpatialMapping編
 
OSC2011 Androidハンズオン
OSC2011 AndroidハンズオンOSC2011 Androidハンズオン
OSC2011 Androidハンズオン
 
第10回ゲームツクール uGUIをアニメーションさせよう
第10回ゲームツクール uGUIをアニメーションさせよう第10回ゲームツクール uGUIをアニメーションさせよう
第10回ゲームツクール uGUIをアニメーションさせよう
 
Flutter のリアクティブ戦略 set state 〜 redux まで
Flutter のリアクティブ戦略 set state 〜 redux までFlutter のリアクティブ戦略 set state 〜 redux まで
Flutter のリアクティブ戦略 set state 〜 redux まで
 
2015年度研究室プレ卒研用Android講座2
2015年度研究室プレ卒研用Android講座22015年度研究室プレ卒研用Android講座2
2015年度研究室プレ卒研用Android講座2
 
FlutterをRenderObjectまで理解する
FlutterをRenderObjectまで理解するFlutterをRenderObjectまで理解する
FlutterをRenderObjectまで理解する
 
デザイナーとエンジニアが話す、iOSアプリケーション開発
デザイナーとエンジニアが話す、iOSアプリケーション開発デザイナーとエンジニアが話す、iOSアプリケーション開発
デザイナーとエンジニアが話す、iOSアプリケーション開発
 
試して感覚を掴んでみるUICollectionViewCompositionalLayout & Combine
試して感覚を掴んでみるUICollectionViewCompositionalLayout & Combine試して感覚を掴んでみるUICollectionViewCompositionalLayout & Combine
試して感覚を掴んでみるUICollectionViewCompositionalLayout & Combine
 
20120620 ngui japanese
20120620 ngui japanese20120620 ngui japanese
20120620 ngui japanese
 
UE4 HUD作成
UE4 HUD作成UE4 HUD作成
UE4 HUD作成
 

Extending the Unity Editor

  • 1. Extending the Unity Editor Unity Editor の 拡張について
  • 2. Extending the Unity Editor まずはUnityのGUIを理解しよう (1/2) ・基本的にデバッグ用 毎フレーム1つ1つのコンポーネントについて判定・再描画が 行われるので重い。また使いこなすにはGUISkinなどの細かい 仕様を覚えなくてはならず面倒。 ・Viewport空間ではなくScreen空間に描画 スクリーンに対する絶対座標で描画されるので、画面解像度が 変わった時に破綻する。 ・フォントの問題 PC/Mac以外で日本語文字を表示しようとすると非常に面倒。 携帯機ではDynamicフォントが使えない。 2/30
  • 3. Extending the Unity Editor まずはUnityのGUIを理解しよう (2/2) ・OnGUI()に表示と処理を一緒くたに書く ゲーム実行中に、ゲームオブジェクトの更新と描画が終わった タイミングでOnGUI()が呼ばれ、そこに記述されている内容が 実行される。 void OnGUI() { if (GUILayout.Button("Next Level")) { Application.LoadLevel("Level2"); } if (GUILayout.Button("Quit")) { Application.Quit(); } } ・拡張エディタの場合もこの辺の仕組みは同じ インスペクタやウィンドウの再描画が必要なタイミングで、 OnInspectorGUI()やOnGUI()が呼ばれる。 3/30
  • 4. Extending the Unity Editor GUIとGUILayout (1/2) ・GUI = 自由配置 第一引数が必ず、位置とサイズを指定するためのRect構造体。 void OnGUI() { GUI.Button(new Rect(10, 10, 100, 50), "Button1"); GUI.Button(new Rect(50, 50, 100, 50), "Button2"); GUI.Button(new Rect(90, 90, 100, 50), "Button3"); text = GUI.TextArea(new Rect(200, 10, 100, 100), text); } 4/30
  • 5. Extending the Unity Editor GUIとGUILayout (2/2) ・GUILayout = 逐次配置 書いていった順に並んで表示される。BeginHorizontalなどで グループ化して並べることも可能。 void OnGUI() { GUILayout.BeginHorizontal(); //水平方向にグループ化 GUILayout.BeginVertical(); //垂直方向にグループ化 GUILayout.Button("Button1"); GUILayout.Button("Button2"); GUILayout.Button("Button3"); GUILayout.EndVertical(); text = GUILayout.TextArea(text, GUILayout.Width(200), GUILayout.Height(60)); GUILayout.EndHorizontal(); } ※インデントは気分。必須ではない。 5/30
  • 6. Extending the Unity Editor EditorGUIとEditorGUILayout (1/2) ・GUI・GUILayoutの関係と同じ EditorGUIは絶対座標指定、EditorGUILayoutは逐次配置。 Editor向けに便利なパーツが用意されている。 ・GUI系とEditorGUI系は混在可能 というよりEditorGUIにはButton等の基本的なパーツはなく、 GUI系と混在させて使うことが前提。 public override void OnInspectorGUI() { GUILayout.BeginHorizontal(); position = EditorGUILayout.Vector3Field("Position", position); if (GUILayout.Button("Reset")) position = Vector3.zero; GUILayout.EndHorizontal(); } 6/30
  • 7. Extending the Unity Editor EditorGUIとEditorGUILayout (2/2) ・基本的にEditorGUILayoutを使用 ゲーム用のGUIがゲーム画面の左上を基準にして配置されるよ うに、エディタ用のGUIはインスペクタやウィンドウの左上を 基準にして配置されていく。 座標を全部自前で計算してもいいが、EditorGUILayoutで配置 しておくとスケーリングが自動で行われるのでスマート。 ・位置調整用のパーツもある 領域のサイズを考慮して自動的に伸縮するFlexibleSpace()や 逆に勝手に伸縮しないようにするGUILayout.ExpandWidth() を上手く使ってかっこ良く配置しよう。 7/30
  • 8. Extending the Unity Editor インスペクタを拡張してみよう (1/5) ・何を拡張できるの? インスペクタに表示されるものなら何でも。 選択中のオブジェクトに対する操作やインスペクタでの表示の され方を独自に記述可能。 ・コンポーネントごとに拡張クラスを定義 拡張インスペクタはインスペクタ全体ではなくTransformとか Cameraとかの各コンポーネント毎にクラスを定義していく。 using UnityEngine; // 必須 using UnityEditor; // 必須 [CustomEditor(typeof(Transform))] // Transformクラス用の拡張であることを表すアトリビュート public sealed class CustomTransformEditor : Editor // Editorクラスを継承する { public override void OnInspectorGUI() // インスペクタが再描画されるタイミングで呼ばれる { ... 8/30
  • 9. Extending the Unity Editor インスペクタを拡張してみよう (2/5) ・どう拡張できるの? 例えば左のようなプロパティを持つコンポーネントを作ったと する。するとインスペクタでの表示は右のようになる。 using UnityEngine; public class Hoge : MonoBehaviour { public Vector3 velocity; } これではVectorの各要素が縦に並んでいて非常に無様である。 しかも初期状態では折りたたまれているし、色々ひどい。 これをTransformの表示のように横に並べたい。 すっきり! 9/30
  • 10. Extending the Unity Editor インスペクタを拡張してみよう (3/5) ・拡張エディタクラスを定義する エディタのProject直下(フォルダ構成としてはAssets直下)に Editorという名前のフォルダを作り、そこに新規スクリプトを 配置。MonoBehaviour向けに書かれている内容をEditor向け に書きなおす。 using UnityEngine; // 必須 using UnityEditor; // 必須 [CustomEditor(typeof(Hoge))] // Hogeクラス用の拡張であることを宣言 public sealed class HogeEditor : Editor { public override void OnInspectorGUI() { DrawDefaultInspector(); // とりあえずデフォルトの表示 } } 10/30
  • 11. Extending the Unity Editor インスペクタを拡張してみよう (4/5) ・拡張エディタクラスを実装する EditorGUILayoutには、そのものズバリVector3Fieldという パーツが用意されているのでそれを利用。 using UnityEngine; using UnityEditor; [CustomEditor(typeof(Hoge))] public sealed class HogeEditor : Editor { public override void OnInspectorGUI() { // 今インスペクタで表示しているオブジェクトのインスタンスがtargetに格納されている Hoge hoge = target as Hoge; // targetプロパティはObject型なので目的の型にキャスト Vector3 v = EditorGUILayout.Vector3Field("Velocity", hoge.velocity); if (v != hoge.velocity) // 変更があった場合のみ処理する { Undo.RegisterUndo(hoge, "Velocity Change"); // アンドゥバッファに登録 hoge.velocity = v; EditorUtility.SetDirty(target); // アセットデータベースに変更を通知 } } } 11/30
  • 12. Extending the Unity Editor インスペクタを拡張してみよう (5/5) ・拡張エディタクラスを堪能する Unityにフォーカスを戻してコンパイルエラーなどがなければ、 インスペクタの表示が以下のように変化している。  Undo.RegisterUndo()して  あるので、Ctrl+Zで取り消し、  Ctrl+Yでやり直しもバッチリ。 12/30
  • 13. Extending the Unity Editor もっと拡張してみよう (1/2) ・リセット・コピー&ペーストの実装 先ほどのプロパティをゼロリセットするボタンと、数値を別の オブジェクトにコピー&ペーストするボタンを付けてみる。 static Vector3 copyBuffer = Vector3.zero; public override void OnInspectorGUI() { Hoge hoge = target as Hoge; Vector3 v = EditorGUILayout.Vector3Field("Velocity", hoge.velocity); EditorGUILayout.BeginHorizontal(); // 水平方向に並べる if (GUILayout.Button("Reset", EditorStyles.miniButton)) // 見た目にこだわってみる v = Vector3.zero; GUILayout.Space(GUILayoutUtility.GetAspectRect(1).width / 3); if (GUILayout.Button("Copy", EditorStyles.miniButtonLeft)) copyBuffer = v; if (GUILayout.Button("Paste", EditorStyles.miniButtonRight)) v = copyBuffer; EditorGUILayout.EndHorizontal(); if (v != hoge.velocity) { Undo.RegisterUndo(hoge, "Velocity Change"); hoge.velocity = v; EditorUtility.SetDirty(target); } } 13/30
  • 14. Extending the Unity Editor もっと拡張してみよう (2/2) ・挙動の確認 Unityにフォーカスを戻してコンパイルエラーなどがなければ、 インスペクタの表示が以下のように変化している。  EditorStylesの指定や空白を  配置したことで、まとまりの  ある見た目にする事ができた。 14/30
  • 15. Extending the Unity Editor 他にもこんな便利なパーツが ・範囲指定 EditorGUILayout.MinMaxSlider() ・ゲージ表示 EditorGUI.ProgressBar() 15/30
  • 16. Extending the Unity Editor 拡張インスペクタの振る舞い (1/2) ・必要な時にnewされている 先ほど実装した拡張インスペクタは、Unityエディタ上で対象の コンポーネントがアタッチされているオブジェクトが選択され る度にnewされている。 従って、1つのオブジェクトを選択している間はインスペクタ 自体のメンバプロパティは保持されるが、別のオブジェクトを 選択するとインスペクタのメンバは初期値に戻る。 複数オブジェクトをまたいでやりとりしたい情報がある場合は staticメンバを利用しよう。 またOnEnable()をオーバーライドすることで、オブジェクト を選択した瞬間の挙動を定義することも可能。 16/30
  • 17. Extending the Unity Editor 拡張インスペクタの振る舞い (2/2) ・必要な時にOnInspectorGUI()が呼ばれる OnGUI()が毎フレーム呼ばれるのと違い、OnInspectorGUI() はインスペクターペインの再描画が必要になったタイミングで 随時呼ばれている。 従って「一定間隔で明滅する」といったような、エディタ上で リアルタイムに何かを動かすような処理は基本的にできない。 (毎回Repaint()を呼びまくれば可能ではある) ・シーンビューの更新時にはOnSceneGUI() インスペクタの親クラスであるEditorにはOnSceneGUI()と いうメソッドもあり、これはシーンビューが更新されるときに 呼ばれている。どう使うのかというと… 17/30
  • 18. Extending the Unity Editor シーンビューも拡張してみよう (1/3) ・ハンドル(マニピュレータ)の表示 ベクトルを下図のようにグラフィカルに表示したい。 18/30
  • 19. Extending the Unity Editor シーンビューも拡張してみよう (2/3) ・ハンドル(マニピュレータ)の表示 拡張インスペクタで取り扱っている情報を、シーンビュー上に グラフィカルに表示すると理解しやすくなる場合がある。 [CustomEditor(typeof(Hoge))] public sealed class HogeEditor : Editor { Hoge hoge = null; void OnEnable() { hoge = target as Hoge; } void OnSceneGUI() { Vector3 root = hoge.transform.position; // 起点を計算 Vector3 cap = root + hoge.velocity; // 終点を計算 Handles.color = Color.magenta; // 色を変更 Handles.DrawLine(root, cap); // 線を描画 Quaternion rot = Quaternion.LookRotation(hoge.velocity); // 終点の向きを計算 float size = HandleUtility.GetHandleSize(cap); // カメラ距離に依らないサイズを計算 Handles.ArrowCap(0, cap, rot, size); // 矢印型の終点を描画 } static Vector3 copyBuffer = Vector3.zero; public override void OnInspectorGUI() 19/30
  • 20. Extending the Unity Editor シーンビューも拡張してみよう (3/3) ・ハンドル(マニピュレータ)の表示 ベクトルがグラフィカルに表示されるようになった。 20/30
  • 21. Extending the Unity Editor 拡張インスペクタの例 21/30
  • 22. Extending the Unity Editor ウィンドウを作ってみよう (1/5) ・何を拡張できるの? Build Settingのようなフローティングウィンドウや、 AnimationウィンドウのようなDock可能なウィンドウ、 あるいは簡単なウィザードなどを独自に作ることができる。 ・ウィンドウごとに拡張クラスを定義 カスタムウィンドウは拡張インスペクタと違い、ウィンドウ 1つ1つが独立したインスタンスとして振舞う。 using UnityEngine; // 必須 using UnityEditor; // 必須 public sealed class MaterialReplacer : EditorWindow // EditorWindowクラスを継承する { [MenuItem("Tool/Replace Material...")] // エディタのメニューに項目が追加される static void OpenWindow() // 上記項目をクリックするとこの関数が呼ばれる { 22/30
  • 23. Extending the Unity Editor ウィンドウを作ってみよう (2/5) ・Floatingウィンドウの場合 public sealed class MaterialReplacer : EditorWindow { [MenuItem("Tool/Replace Material...")] static void OpenWindow() // メニューから呼ばれるためにはstatic関数でなければならない { EditorWindow.GetWindow<MaterialReplacer>(true, "Replace Material"); } } 23/30
  • 24. Extending the Unity Editor ウィンドウを作ってみよう (3/5) ・Dockableウィンドウの場合 public sealed class MaterialReplacer : EditorWindow { [MenuItem("Tool/Replace Material...")] static void OpenWindow() // メニューから呼ばれるためにはstatic関数でなければならない { EditorWindow.GetWindow<MaterialReplacer>(false, "Replace Material"); } } Dock可能 24/30
  • 25. Extending the Unity Editor ウィンドウを作ってみよう (4/5) ・OnGUI()にレイアウトを実装 拡張インスペクタと同じ要領で、OnGUI()をオーバーライドし そこへレイアウトを入れこんでいく。 [MenuItem("Tool/Replace Material...")] static void OpenWindow() { EditorWindow.GetWindow<MaterialReplacer>(false, "Replace Material"); } static Material targetMaterial = null; void OnGUI() { targetMaterial = EditorGUILayout.ObjectField( "Material", targetMaterial, typeof(Material), false ) as Material; GUI.enabled = (targetMaterial != null) && (Selection.gameObjects.Length > 0); if (GUILayout.Button("Replace!")) { foreach (var renderer in from go in Selection.gameObjects select go.renderer) if (renderer != null) renderer.sharedMaterial = targetMaterial; } GUI.enabled = true; } 25/30
  • 26. Extending the Unity Editor ウィンドウを作ってみよう (5/5) ・ウィンドウが完成 選択中のゲームオブジェクト全てのマテリアルを、指定した ものに差し替えるツールが完成。 マテリアルを選択し、差し替え たいオブジェクトを選択状態に したらReplaceボタンを押す 選択中のオブジェクトにレンダラが付い ていれば、そのマテリアルが差し替わる 26/30
  • 27. Extending the Unity Editor 覚えておきたい (1/4) ・Selectionクラス エディタ上で選択中のオブジェクトには、Selectionクラスを 通してアクセスできる。 27/30
  • 28. Extending the Unity Editor 覚えておきたい (2/4) ・Undoクラス スクリプトから変更した情報は、何もしないとUndoの履歴に 残らない。エディタの拡張をする場合はUndo.RegisterUndo を有効に使い、ユーザーの利便性を図ろう。 28/30
  • 29. Extending the Unity Editor 覚えておきたい (3/4) ・EditorUtility、FileUtilなどのユーティリティ EditorUtilityにはファイルオープンダイアログやYes/No形式 のダイアログを表示するためのメソッド、FileUtilにはファイル のコピーや削除などを行うメソッドなど、色々便利なインター フェースが用意されている。 ・スクリプトから全ての設定にアクセス可能 PlayerSettingsやEditorUserBuildSettingsなどを通して、 エディタ上で触れる設定項目は全てスクリプトからも操作が 可能。面倒な処理はバッチ化してしまえ。 29/30
  • 30. Extending the Unity Editor 覚えておきたい (4/4) ・ファイル出力やシステムコールも可能 System.IO.StreamWriterを使ってgmcs.rspを書きだしたり System.Diagnostics.Processを使ってシステムコールを 呼び出すことも可能。Unity組み込みのWWWクラスを使って 簡単にウェブサーバと連携したり、可能性は無限大。 30/30