fc2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »インスペクタ
このページの記事一覧

【Unity】【エディタ拡張】インスペクタのフィールドに属性で色を付ける  


 以前インスペクタのフィールドを入力不可にする PropertyAttribute を作ったが、Unity2019.4 以降は Personal(無料)アカウントでもダークテーマを使えるようになったので、無効の色(グレー:たぶんアルファが低くなる)が少し見ずらく感じるようになったんだよね…。

●ライトテーマ(Unity2018)時の入力不可(Disable)属性を付けたフィールド

●ダークテーマ(Unity2020)での入力不可(Disable)属性を付けたフィールド


 なのでいっそのこと自分の好きな色にできないかとググったが、なぜか込み入ったコードしか見つからなかったので、Disable 属性と同じ要領で色を付けられるかと試してみたら、意外と簡単にできたので、コードを載せておこう。無効化とは併用できなかったが(グレーになってしまう)、自分でフィールドを色で見分けるくらいの用途なら十分に役に立つと思う。

(※) Unity 2020.3.34f1 / Windows10(x64) で確認

●デバッグ用途のフィールドに色を付ける例(属性):DebugFieldAttribute.cs
using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace Example
{
public class DebugFieldAttribute : PropertyAttribute
{
//※中身は空で良い
}

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(DebugFieldAttribute))]
public class DebugFieldDrawer : PropertyDrawer
{
static readonly Color _color = Color.green; //色を指定

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var tmpColor = GUI.color; //一時退避
GUI.color = _color;
EditorGUI.PropertyField(position, property, label, true);
GUI.color = tmpColor;
}
}
#endif
}

●クラス内部値用途のフィールドに色を付ける例(属性):InternalAttribute.cs
using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace Example
{
public class InternalFieldAttribute : PropertyAttribute
{
//※中身は空で良い
}

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(InternalFieldAttribute))]
public class InternalFieldDrawer : PropertyDrawer
{
static readonly Color _color = Color.cyan; //色を指定

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var tmpColor = GUI.color; //一時退避
GUI.color = _color;
EditorGUI.PropertyField(position, property, label, true);
GUI.color = tmpColor;
}
}
#endif
}

●実際にインスペクタで表示してみる例(メインコード等):FieldColorTest.cs
using UnityEngine;

public class FieldColorTest : MonoBehaviour
{
[SerializeField, DebugField] string debugValue = "hoge";
[SerializeField, InternalField] int internalValue = 123;
[SerializeField, Disable] float disableValue = 3.141592f; //Disable 属性は以前に作ったもの
[SerializeField] string normalValue = "piyo";
}

●ダークテーマ(Unity2020)での色を付けたフィールド

 今回はエディタスクリプト部分をプリプロセッサ(UNITY_EDITOR)で囲んでしまったが、Disable 属性のときのようにスクリプトを分けて「Editor」フォルダに PropertyDrawer を継承したスクリプトを置いても良い。"DebugField", "InternalField" の名前は任意なので、自分で好きに付けると良いだろう。とても簡単なスクリプトだが、名前と色だけ変えて使い回せば、インスペクタも結構見やすくなった。思いつきだったが、何個かあらかじめ定義しておけば、簡単に色分けで分類できて、意外と便利だったので、誰かの役に立つと嬉しい。


(PropertyAttribute, PropertyDrawer をもっと知りたいときは、以下を参照)
UnityのAttribute(属性)についてまとめてメモる。
自分だけのPropertyDrawerを作ろう!


(関連記事)
【Unity】【エディタ拡張】インスペクタで入力不可(Disable)な属性を作る
【Unity】インスペクタの値を保持したまま変数をリネームする
【Unity】【C#】インスペクタでの UnityEvent のコールバック登録の有無を調べる
【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録
【Unity】【エディタ拡張】インスペクタの表示項目を動的に変更する
【Unity】【エディタ拡張】独自のギズモ(Gizmo)を表示する


関連記事
スポンサーサイト



category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  Unityリファレンス  インスペクタ  エディタ拡張 
tb: 0   cm: --

【Unity】【エディタ拡張】インスペクタの UnityEvent を並べ替え可能にする  


 前回「インスペクタの配列やリストを並べ替え」を紹介したが、UnityEvent も並べ替えたいときもよくあるだろう。これもとても導入・利用が簡単なものがあるので、ついでに紹介しておこう。

EasyEventEditorMIT License

 また、あまりオープンソースに馴染みの無い人のためにも、導入方法も詳しく書いておく。慣れている人なら自分の方法でも構わない。といっても導入しただけで使えるスグレモノなので、簡単な使い方だけ見ておけば、すぐに使えると思う。


(※) Unity 2019.2.21f1 / Windows10(x64) で確認



■ライブラリのインポート

 まずは github でライブラリをダウンロードしよう。「Clone or download」から zip をダウンロードしても良いが、Releases ページにある .unitypackage を使う方が簡単なので、ここではそのやり方で導入してみよう。


Releases ページ(.unitypackage がダウンロードできる)

 .unitypackage をダウンロードしたら、プロジェクトビューにドラッグドロップしよう。ファイルは1つしかないので(※掲載時点:v1.0.1)、そのままインポートすれば良い。これだけで導入は完了だ。





 尚、zip の方には asmdef(Assembly Definition Files)やパッケージマネージャーでの導入するための package.json などが入っている。こちらの方法はまた別の方法となるので(あと、Unity のバージョンによるので)、興味があったら参考資料だけ載せておこう。

【Unity】Assembly Definition Filesという神機能
プロジェクト管理は進化しています – Unity Package Manager の概要
UnityのPackage Managerを使って機能をインストールする



■インスペクタで並べ替えてみるためのサンプルコード

 ここからは簡単なコードを書いて試してみよう。内容はかなり適当なので、好きなように書き換えて欲しい。

 もしあまり UnityEvent を使ったことないから、色々なイベントコールバックをするサンプルコードが以下の記事にまとめてあるので、参照して欲しい。

【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録

●インスペクタで並べ替えてみるためのサンプルコード(※.NET 4.x)
using UnityEngine;
using UnityEngine.Events;

public class EasyEventEditorTest : MonoBehaviour
{
//これがインスペクタに表示される
public UnityEvent OnCallback;

//UnityEvent のコールバック用1
public void Hoge()
{
Debug.Log("Hoge");
}

//UnityEvent のコールバック用2
public void Fuga()
{
Debug.Log("Fuga");
}

//UnityEvent のコールバック用3
public void Piyo()
{
Debug.Log("Piyo");
}

//UI-Button などの OnClick などに登録する等
public void Click()
{
OnCallback?.Invoke(); //コールバック発火
}
}

 このスクリプトをヒエラルキーで何らかの GameObject にアタッチしよう。

 後はインスペクタで実際に確認して欲しい(表示が更新されてなかったら、一旦フォーカスを外して、再度スクリプトをアタッチした GameObject を見てみると反映されてたりする ← Unity はコンパイルが走ると表示がデフォに戻ることがある)。

●左端にハンドルが付く


●ドラッグで移動できる


●移動後


 Click() を UI の Button に登録して試してみればわかるが(面倒なら Start() から呼んでも良い)、コールバックの発火はインスペクタで登録した上→下の順になる。試してみよう。

●並べ替え前
Hoge
Fuga
Piyo

●並べ替え後(※並び替えた順)
Piyo
Hoge
Fuga


 また、機能をオフにしたり、表示方法を変更したりする設定は「Edit>Preference」で「Easy Event Editor」タブ(Unity2019以降)にある。自分の見やすい設定にしておくと良いだろう。







(関連記事)
【Unity】【C#】インスペクタの配列やリストを並べ替え可能にする
【Unity】【C#】インスペクタで入力不可(Disable)な属性を作る
【Unity】【C#】インスペクタの値を保持したまま変数をリネームする
【Unity】【C#】インスペクタの表示項目を動的に変更する
【Unity】【C#】インスペクタでの UnityEvent のコールバック登録の有無を調べる
【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録


関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityオープンソースライブラリ  Unityプラグイン  インスペクタ  エディタ拡張 
tb: 0   cm: --

【Unity】【エディタ拡張】インスペクタの配列やリストを並べ替え可能にする  


 この手のエディタ拡張はググればいくつか出てくるが、今回は特に導入・利用が簡単な「Reorderable Inspector」というオープンソースライブラリを紹介しよう。また、コード上で属性を付けるだけで、既に作ってあるものに後から機能追加できることも、このライブラリの魅力だ。

Reorderable InspectorMIT License

※Unity2020LTS では標準で利用できるようになりました(導入不要)

 あまりオープンソースに馴染みの無い人のためにも、導入方法も詳しく書いておく。慣れている人なら自分の方法でも構わない。それではやってみよう。


(※) Unity 2019.2.21f1 / Windows10(x64) で確認



■ライブラリのインポート

 まずは github でライブラリをダウンロードしよう。「Clone or download」から zip をダウンロードできるので、落としたら zip を解凍する。


Reorderable InspectorMIT License

 解凍したらいくつかファイルが出てくるので、プロジェクトビューで「Scripts」(名前は任意)フォルダを用意し、「ReorderableAttribute.cs」「EditScriptableAttribute.cs」をプロジェクトビューにドラッグ&ドロップしてインポートする

 また「Editor」以下のファイルも必要なので、フォルダごとインポートするか、自分で「Editor」(場所はどこでも構わないが、名前は "Editor" 固定)フォルダを作り、「ReorderableArrayInspector.cs」「SerializedPropExtension.cs」をインポートする。これだけで導入は完了だ。





■インスペクタで並べ替え可能な配列やリストを表示する

 ここからは簡単な使用例となる。配列やリストの変数名などは自分の任意で構わない。既に何らかのプロジェクトがあるのなら、それを使っても良い。

●ReorderableInspector の使用例
using System.Collections.Generic;
using UnityEngine;
using SubjectNerd.Utilities;

public class ReorderableInspectorTest : MonoBehaviour
{
//配列の例(public フィールド例)
[Reorderable]
public string[] strArray = { "Apple", "Banana", "Candy" };

//リストの例(private フィールド例)
[SerializeField, Reorderable]
List<string> strList = new List<string>() { "xxx", "yyy", "zzz" };
}

 要素の内容は適当だが、このスクリプトをヒエラルキーで何らかの GameObject にアタッチしよう。

 コードの要点としては「using SubjectNerd.Utilities;」を入れることと、フィールドに "[Reorderable]" を追加するということだ。逆に元に戻したければ "[Reorderable]" をコメントアウトするか、削除すれば良い。

 後はインスペクタで実際に確認して欲しい(表示が更新されてなかったら、一旦フォーカスを外して、再度スクリプトをアタッチした GameObject を見てみると反映されてたりする ← Unity はコンパイルが走ると表示がデフォに戻ることがある)。



●各項目をドラッグして並べ替えられるようになる


 もし、並び替え機能を自作したいなら、以下の資料を参考にすると良いだろう。ただ、自作となると Reflection の知識が必要となるので、結構大変だと思う(実は私も独自に作ってたのがあるが、結局このライブラリの方が楽なので、最近はこっちしか使ってない(笑))。興味があったら調べてみるのも良いだろう。

エディタ拡張で配列の入れ替えが簡単に出来るReorderableListの使い方と全コールバック【Unity】【エディタ拡張】
.NET のリフレクション
System.Reflection





(関連記事)
【Unity】【C#】インスペクタの UnityEvent を並べ替え可能にする
【Unity】【C#】インスペクタで入力不可(Disable)な属性を作る
【Unity】【C#】インスペクタの値を保持したまま変数をリネームする
【Unity】【C#】インスペクタの表示項目を動的に変更する
【Unity】【C#】インスペクタでの UnityEvent のコールバック登録の有無を調べる
【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録


関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityオープンソースライブラリ  Unityプラグイン  インスペクタ  エディタ拡張 
tb: 0   cm: --

【Unity】【エディタ拡張】インスペクタで入力不可(Disable)な属性を作る  


 インスペクタに表示するだけで、インスペクタからは入力はできないフィールドを作りたいときは良くある。デバッグ用に表示だけしたいときとかね。

 サードパーティのインスペクタの拡張アセットなどにはよく付いているのだが、インポートするまでもなく、簡単に済ませたいときなどに便利なので掲載しておこう。何でもかんでもアセット導入すると、ファイルが増えすぎてビルド時間も長くなるしね。自作なら色々応用効くのも魅力だ(笑)。

(※) Unity 2018.4.8f1 / Windows10(x64) で確認



 必要なスクリプトは PropertyAttribute を継承した属性用スクリプトと、PropertyDrawer を継承したエディタ(インスペクタ)用スクリプトになる。エディタ表示用スクリプトは「Editor」フォルダを作って、そこに置いておく必要がある。

PropertyAttribute
PropertyDrawer



●属性用スクリプト:DisableAttribute.cs
using UnityEngine;

public class DisableAttribute : PropertyAttribute
{
//※中身は空で良い
}

●エディタ表示用スクリプト:DisableDrawer.cs
using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(DisableAttribute))]
public class DisableDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
GUI.enabled = false; //ここで入力不可にしている
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = true; //元に戻しておく
}
}


 例として適当な GameObject にテスト用スクリプトをアタッチして、インスペクタの表示を見てみよう。



●テスト用スクリプト:DisableAttributeTest.cs(※名前は任意)
using UnityEngine;

public class DisableAttributeTest : MonoBehaviour
{

[Disable] public string str = "hoge"; //インスペクタからは入力できない
[SerializeField, Disable] int num = 1; //インスペクタからは入力できない

[HideInInspector] public float f = Mathf.PI; //※これは単にインスペクタに表示しない例
}

 今回作ったのは "[Disable]" という属性だ。以前のバージョンでは "[DisableAttribute]" と書く必要があったらしいが、現在の Unity バージョンでは "Attribute" は省略できる。

 "[HideInInspector]" は単に表示したくないときの属性で、元々 Unity にビルトインされている。他にも色々な属性があるので、少し古いが、以下に資料を載せておこう。

UnityのAttribute(属性)についてまとめてメモる。

 アセットによっては "[ReadOnly]" などになってるかもだが、C# Job System でも使われる属性なので、今後はコンフリクトするかも知れない。その場合は namespace を付けておくのも一つの手だ。もっと色々自作したいなら、以下も少し古いが、資料を載せておこう。

自分だけのPropertyDrawerを作ろう!






(関連記事)
【Unity】インスペクタの値を保持したまま変数をリネームする
【Unity】【C#】インスペクタの配列やリストを並べ替え可能にする
【Unity】【C#】インスペクタの UnityEvent を並べ替え可能にする
【Unity】【C#】インスペクタでの UnityEvent のコールバック登録の有無を調べる
【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録
【Unity】【C#】インスペクタの表示項目を動的に変更する
【Unity】【C#】独自のギズモ(Gizmo)を表示する


関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityリファレンス  エディタ拡張  インスペクタ 
tb: 0   cm: --

【Unity】【C#】インスペクタの値を保持したまま変数をリネームする  


 最近は色々なオープンソースを利用しているのだが、時折アップデートしたらプロジェクトが破壊されることもある。その1つがインスペクタの参照だろうか?

 残念ながら、インスペクタに設定されていたフィールド名を変えると、参照が外れることはよくあることだ。これが大量にあったら・・・まぁ、まともに動かなくなることは想像できるだろう(笑)。

 これは FormerlySerializedAs というものを使えば、回避できるのだが、微妙に凡例が長かったり、必要なものが欠けてたりと、ちょっとわかりずらいと思ったので、もっと簡単な例をメモ代わりに書いておこうと思った。

FormerlySerializedAsAttribute(公式マニュアル)

(※) Unity 2018.4.6f1 / Windows10(x64) で確認



■簡単な手順

 例として、ボタンの参照しているフィールドを

[SerializeField] private Button hogeButton;
 ↓
[SerializeField] private Button _hogeButton;


のように変更したいとする。インスペクタの表示名は変わらないが(hogeButton, _hogeButton, m_hogeButton などはコード内では別物だが、インスペクタでの表示は同じになる)、普通にリネームすると、これまで設定していたボタンへの参照が外れる。これをそのまま保持してリネームしたいという感じだ。

1.「using UnityEngine.Serialization;」をファイルの先頭に追加する。

2.[FormerlySerializedAs] の属性を加え、現在のフィールド名(変更前の名前)を入れる。

using UnityEngine.Serialization;

public class Example : MonoBehaviour
{
[FormerlySerializedAs("hogeButton")]
[SerializeField] private Button hogeButton;
}


3.フィールド名をリネーム(リファクタリング)して、一旦、シーンを保存する。また、プレファブ化してるものは個々に保存[Override]しておかないと参照が外れることがある(※要エディタでプレイ前に保存)。

using UnityEngine.Serialization;

public class Example : MonoBehaviour
{
[FormerlySerializedAs("hogeButton")]
[SerializeField] private Button _hogeButton;
}


4.インスペクタで値が保持されているのを確認できたら、FormerlySerializedAs 属性や using は削除しても良い(※複数から参照しているときは注意)。

using UnityEngine.Serialization;

public class Example : MonoBehaviour
{
[SerializeField] private Button _hogeButton;
}


 まぁ、それでも大量にあったら大変だけどね。できればリリース後は、public なものや過去のリソースに影響を与える変更は、極力控えて貰いたいなぁ・・・(バグとかクリティカルなものならともかく・・・ただの命名規則の変更で無駄に時間とられるのは勘弁・・・)。|||orz


(参考)
FormerlySerializedAsAttribute(公式マニュアル)
PrefabやSceneのSerializeされた変数の値を保持したままリネームする
FormerlySerializedAs(テラシュールブログ)






(関連記事)
【Unity】【C#】インスペクタで入力不可(Disable)な属性を作る
【Unity】【C#】インスペクタの配列やリストを並べ替え可能にする
【Unity】【C#】インスペクタの UnityEvent を並べ替え可能にする
【Unity】【C#】インスペクタの表示項目を動的に変更する
【Unity】【C#】インスペクタでの UnityEvent のコールバック登録の有無を調べる
【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録
【C#】【Unity】enum 型と string, int 型の相互変換など


関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityトラブルシューティング  Unityリファレンス  エディタ拡張  インスペクタ 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop