こちらはクラスター Advent Calendar 2023(2ページ目)の16日目の記事です!
前日は @kitta65 さんの「趣味開発のフォーマッタが業務でちょっと役立った話」でした!larkを初めて知ったので、今度何かつくってみたいですね。
こんにちは、スワンマンです。クラスター株式会社で主にイベントディレクターとかスワンマンをしています。
はじめに
今回Editorを使わずにインスペクタを拡張したいんですよ。EditorというのはUnityのクラスで、特定の型をインスペクタ上でいい感じに表示するのに役立つあれですが、今回はそのEditorを使わずに適当な位置に適当なボタンをねじ込みたいんです。
なお、何故そうしたいのかはこの際置いておくこととします。
※今回の内容はUnity 2021.3.4f1上での話です
PropertyCallbackScope
EditorGUIUtilityにPropertyCallbackScopeというメソッドがあります。
プロパティの表示前にコールバックが行われるスコープを設定するためのもので、公式リファレンスを見る感じではこう使えということらしいです。
class MyEditor : EditorWindow
{
void OnGUI()
{
using (var s = new EditorGUIUtility.PropertyCallbackScope((rect, property) => { Debug.Log($"About to draw property path {property.propertyPath}"); }))
{
// Block of code with controls
}
}
}
これ、あたかもOnGUIなどのUI描画の中だけで使えそうな雰囲気を醸し出してますが、全然そんなことはなく違う場所からも呼び出すことが可能です。
そしてUIの描画に関係ないところで生成しっぱなしにすると、全てのプロパティの描画前にコールバックされるようになります。
例えばこんなコードを書くと、
public class TotemoHidoiFurumai
{
static EditorGUIUtility.PropertyCallbackScope scope;
[InitializeOnLoadMethod]
static void Initialize()
{
scope = new EditorGUIUtility.PropertyCallbackScope((rect, prop) => EditorGUILayout.LabelField(prop.propertyPath));
}
}
これでいい感じのプロパティの位置が分かったので、あとはこんな感じでボタンをねじ込みます。
public class SugokuHidoiFurumai
{
static EditorGUIUtility.PropertyCallbackScope scope;
[InitializeOnLoadMethod]
private static void Initialize()
{
scope = new EditorGUIUtility.PropertyCallbackScope((rect, prop) =>
{
if (prop.serializedObject.targetObject.GetType().Name != "Transform") return;
if (prop.propertyPath != "m_LocalScale") return;
if (GUILayout.Button("押す"))
{
Debug.Log("やあ");
}
});
}
}
こうして、この世にまたひとつクソコードが生み出されました。
より良い記事への旅立ち
明日は @MatchaChoco010 さんの「四足歩行アバターを無理やり作る話」です。無理矢理のバトンを明日へ😉