こちらの記事ではbool型変数によって,変数の編集可/不可・表示/非表示を制御していました
が,本記事ではそれの拡張版で,int/enum,string,float型の変数によっても制御できるようにします.
(本記事だけで内容は完結してますので,前記事を事前に読む必要はありません)
つまり何ができるか,ということですが,
例えばこういう実装で
public class ConditionalDisableAttrTest : MonoBehaviour { public enum FlagEnum { A, B, C } [Header("Enum control")] public FlagEnum flagEnum = FlagEnum.A; [ConditionalDisableInInspector("flagEnum", (int)FlagEnum.A)] public string editableStrIfEnumA = "AAA"; [ConditionalDisableInInspector("flagEnum", (int)FlagEnum.B)] public string editableStrIfEnumB = "BBB"; [ConditionalDisableInInspector("flagEnum", (int)FlagEnum.C)] public string editableStrIfEnumC = "CCC"; }
こういう感じに編集可/不可を制御できたり,
こうすれば,
public class ConditionalDisableAttrTest : MonoBehaviour { [System.Serializable] public struct TestStruct { public Vector3 p; public Quaternion q; } [Header("String control")] public string flagStr = "A"; [ConditionalDisableInInspector("flagStr", "A", conditionalInvisible: true)] public TestStruct visibleStructIfA; }
表示/非表示を制御できたりします.(自作クラス/構造体も可)
こういうことをしたくて「Unity インスペクタ 変数 動的」とかでググると,CustomEditorを使う方法が出てきます.
- 【Unity】インスペクタの表示を動的に変更する - Qiita
- インスペクタで設定できる値を動的に変更する【Unity】【エディタ拡張】 - (:3[kanのメモ帳]
- コガネブログ(旧)[Unity]Inspectorに無効にできるグループを表示する
が,これだとCustomEditorで対応したクラスでしか使えない = 他のクラスの変数に使い回しができなくて,ちょろっと使いたいときに不便な感じです.
(プロダクトレベルとかで,しっかり作り込む場合はこちらの方がいいと思いますが)
ということで,今回はCustomEditorは使わずに,任意のクラスの変数に適用できるAttributeを使って実装しています.
正直Unityのエディタ拡張は全然詳しくないので,バグってたらすみません.
一通りの型で使えることは確認しましたが,漏れもあるだろうし,基本正常系しか確認できてません.他のAttributeとの組合せ時とかも未検証です(免責事項)
あまり複雑な実装はいらない,以下のようにシンプルにbool変数で制御するだけでよい,という方は,前記事をご覧ください
編集可/不可 | 表示/非表示 |
---|---|
使い方
まず,AttributeとEditor拡張のクラスを用意します.その後,編集不可にしたり非表示にしたい変数に対してAttributeをつけます.
というだけです.順番に見ていきます.
AttributeとEditor拡張のクラスの作成
以下に貼ったコードのファイルを作成します.
1つ目(ConditionalDisableDrawer.cs
)をEditorフォルダに,2つ目(ConditionalDisableInInspectorAttribute.cs
)は普通にScriptフォルダに,スクリプトファイルを作ってください.
gist77dd59ad1c764387ec5fca3c185e04c2
これで準備OKです.
アトリビュートの利用方法(int)
あとは,任意のMonoBehaviourなクラスの,インスペクタ上の表示制御したい変数にConditionalDisableInInspector
アトリビュートをつけて,第一引数に制御用変数の変数名をstringで,第二引数に比較対象の値を設定してください.
制御用変数がintのとき,具体的には以下のようにします.
public int flagInt = 1; [ConditionalDisableInInspector("flagInt", 1)] public string editableStrIf1;
第一引数の文字列(この例だと"flagInt")が示す変数(flagInt
)が,第二引数(この例だと1
)と同じときに編集可に,flagInt
が1
ではないときに編集不可になります.
(もちろん第二引数の比較対象は1以外でも大丈夫です.利用状況によって設定してください)
逆にしたい場合,つまりflagInt
が1
ではないときに編集可にしたい場合は,notEqualThenEnable
を明示的にtrueにしてください.
[ConditionalDisableInInspector("flagInt", 1, notEqualThenEnable: true)] public Gradient editableGradUnless1;
また,編集可/不可ではなく,表示/非表示を制御したい場合はconditionalInvisible
をtrueにしてください.notEqualThenEnable
と併用も可能です.
[ConditionalDisableInInspector("flagInt", 1, conditionalInvisible: true)] public Color visibleColorIf1; [ConditionalDisableInInspector("flagInt", 1, notEqualThenEnable: true, conditionalInvisible: true)] public Bounds visibleBoundsUnless1;
すべて合わせると,以下のようになります.
アトリビュートの利用方法(enum)
int型で制御できるので,つまりenumでも制御が可能です.
以下のように,第一引数をenumの変数名"flagEnum",第二引数を比較したいenumをintにキャストして入れてください.
// --------- public enum FlagEnum { A, B, C } public FlagEnum flagEnum = FlagEnum.A; [ConditionalDisableInInspector("flagEnum", (int)FlagEnum.A, conditionalInvisible: true)] public string visibleStrIfEnumA = "A"; [ConditionalDisableInInspector("flagEnum", (int)FlagEnum.B, conditionalInvisible: true)] public string visibleStrIfEnumB = "B"; [ConditionalDisableInInspector("flagEnum", (int)FlagEnum.C, conditionalInvisible: true)] public string visibleStrIfEnumC = "C";
このとき,Inspector上では以下のような挙動になります.
この例では使っていないですが,intと同様にnotEqualThenEnable
も使えます.
アトリビュートの利用方法(string)
string型の変数によって他の変数の編集不可・非表示を扱うためには,以下のように,ConditionalDisableInInspector
アトリビュートをつけて,第一引数に制御用変数(string)の変数名をstringで,第二引数に比較対象の文字列を設定してください.
制御用変数(この例ではflagStr
)が,第二引数の文字列(この例では"A")と同じであれば編集可,異なれば編集不可になります.
public string flagStr = "A"; [ConditionalDisableInInspector("flagStr", "A")] public AnimationCurve editableAminCurveIfA;
逆にしたい場合,つまりflagStr
が"A”と異なる場合に編集可にしたい場合は,notEqualThenEnable
をtrueに設定してください.
[ConditionalDisableInInspector("flagStr", "A", notEqualThenEnable: true)] public Vector2 editableVec2UnlessA;
編集可/不可ではなく,表示/非表示を制御したい場合はconditionalInvisible
をtrueに設定してください.notEqualThenEnable
と併用も可能です.
[ConditionalDisableInInspector("flagStr", "A", conditionalInvisible: true)] public Quaternion visibleQuatIfA; [ConditionalDisableInInspector("flagStr", "A", notEqualThenEnable: true, conditionalInvisible: true)] public int visibleIntUnlessA;
すべて合わせると,以下のようになります.
アトリビュートの利用方法(float)
int(enum),stringに続き,float型変数での編集不可・非表示制御の方法です.
float型でも同様に,ConditionalDisableInInspector
アトリビュートをつけて,第一引数に制御用変数(string)の変数名をstringで,第二引数に比較対象のfloat値を設定してください.
public float flagFloat = 0f; [ConditionalDisableInInspector("flagFloat", 0f)] public GameObject editableGameObjIfOver0;
int(enum),stringでの制御と異なり,このとき,flagFloat
が第二引数(ここでは0f
)より大きければ編集可に,小さければ編集不可になります.
挙動を逆にしたい場合,flagFloat
が第二引数の0f
より小さいときに編集可にしたい場合は,greaterThanComparedThenEnable
をfalseに設定してください.
[ConditionalDisableInInspector("flagFloat", 0f, greaterThanComparedThenEnable: false)] public FlagEnum editableEnumIfUnder0Or0;
また,編集可/不可ではなく表示/非表示にしたい場合は,他と同じくconditionalInvisible
をtrueにしてください.
[ConditionalDisableInInspector("flagFloat", 0f, conditionalInvisible: true)] public List<float> invisibleListIfOver0; [ConditionalDisableInInspector("flagFloat", 0f, greaterThanComparedThenEnable: false, conditionalInvisible: true)] public Vector3 invisibleVec3IfUnder0Or0;
すべて合わせると,こんな感じです.
アトリビュートの利用方法(bool)
もちろんbool変数でも制御可能です.
ConditionalDisableInInspector
アトリビュートをつけて,第一引数に制御用bool変数の変数名をstringで指定してください.
public bool flag = false; [ConditionalDisableInInspector("flag")] public string editableStrIfTrue = "a";
挙動を逆にしたい場合,つまり,flag
がfalseのときに編集可にしたい場合は,AttributeのtrueThenDisable
引数をtrueに設定してください.
[ConditionalDisableInInspector("flag", trueThenDisable: true)] public Rect editableRectIfFalse;
また,編集可/不可ではなく,表示/非表示を切り替えたい場合は,conditionalInvisible
をtrueに設定してください.trueThenDisable
も併用可能です.
[ConditionalDisableInInspector("flag", conditionalInvisible: true)] public float visibleFloatIfTrue = 0f; [ConditionalDisableInInspector("flag", trueThenDisable: true, conditionalInvisible: true)] public Vector3 visibleVec3IfFalse;
この4つを並べると,以下のようになると思います.
簡単な解説
実装的な実現方法については,前記事と同じなのでこちらの「簡単な解説」を参照ください
最後に
とりあえず実装しちゃいましたが,floatで制御したいときってどういうときか自分でもよくわからんですね笑
boolはもちろん,int, enum, stringまではありそうですが,float制御の有益な利用の仕方があれば教えてくださいw