- 2023/09/02 【Unity】【エディタ拡張】Game View の解像度を取得する
- 2022/10/01 【Unity】【エディタ拡張】フィールドの値などをインスペクタで横に並べて表示する
- 2022/02/20 【Unity】【エディタ拡張】Project Settings (Graphics Settings) をスクリプトで変更する
- 2020/11/11 【Unity】【エディタ拡張】ヒエラルキー(シーン)の Image, RawImage に使われている画像(Texture)を検出するエディタ拡張(ツール)
- 2020/04/27 【Unity】【エディタ拡張】インスペクタの UnityEvent を並べ替え可能にする
« prev next »
【Unity】【エディタ拡張】Game View の解像度を取得する 
2023/09/02 Sat [edit]
ランタイム時の画面解像度は (Screen.width, Screen.height) で取得できるのだが、エディタスクリプト上で Screen で画面解像度を取得すると、よくわからない値になる。

調べてみたら、UnityStats.screenRes というプロパティ(Unityマニュアルではなぜか見つからない)で取得できるとあったので、いつものように静的な関数として定義しておくと便利だと思った。簡単なサンプルを載せておこう。
(※) Unity 2020.3.34f1 / Windows11(x64) で確認
●Game View の解像度を取得する (戻値:Vector2Int 型)
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
public static partial class Utils //※クラス名は任意
{
/// <summary>
/// Game View の解像度を取得する (戻値:Vector2Int 型)
/// 2023/09/02 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-431.html
/// </summary>
/// <returns>x = width, y = height</returns>
public static Vector2Int GetGameViewResolution()
{
var res = UnityStats.screenRes.Split('x'); //"1920x1080" 等
return new Vector2Int(int.Parse(res[0]), int.Parse(res[1]));
}
}
#endif
●エディタスクリプトからの使用例 (戻値:Vector2Int 型)
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(GameViweResoTest))] //クラス名は任意(ヒエラルキーにアタッチ)
public class GameViweResoTestEditor : Editor //クラス名は任意(※Editorフォルダに置く)
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
GUILayout.Space(15);
if (GUILayout.Button("GameViewResolution"))
{
Debug.Log($"Screen: {Screen.width}x{Screen.height}");
var reso = Utils.GetGameViewResolution();
Debug.Log($"GameViewResolution: {reso.x}x{reso.y}");
}
GUILayout.Space(15);
}
}
戻値に Vector2Int を使ってるが、x が width, y が height となる。
ここでは MonoBehaviour を継承した適当なスクリプト(GameViweResoTest.cs)を作成し、ヒエラルキーにアタッチしている。
1280x720, 1920x1080 等、定番の解像度を使ってるが、「Free Aspect」の状態でも取得できるようだ。そのときに 425x776 など、実際の画面上の解像度(?)になるらしい。

●結果例 (GameView: 4K UHD)
GameViewResolution: 3840x2160
GameViewResolution (Tuple): 3840x2160
現在の Unityバージョン(掲載時点:Unity2020)だと C# も Tuple 型が使えるので(必要なら、.Net 4.x にする)、戻値を Tuple 型にしておくと、少しばかり簡潔になるので良いかもしれない。
●Game View の解像度を取得する (戻値:Tuple 型)
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
public static partial class Utils //※クラス名は任意
{
/// <summary>
/// Game View の解像度を取得する (戻値:Tuple 型)
/// 2023/09/02 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-431.html
/// </summary>
/// <returns>w = width, h = height</returns>
public static (int w, int h) GetGameViewResolutionAsTuple()
{
var res = UnityStats.screenRes.Split('x'); //"1920x1080" 等
return (int.Parse(res[0]), int.Parse(res[1]));
}
}
#endif
●エディタスクリプトからの使用例 (戻値:Tuple 型)
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(GameViweResoTest))] //クラス名は任意(ヒエラルキーにアタッチ)
public class GameViweResoTestEditor : Editor //クラス名は任意(※Editorフォルダに置く)
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
GUILayout.Space(15);
if (GUILayout.Button("GameViewResolution"))
{
Debug.Log($"Screen: {Screen.width}x{Screen.height}");
var (w, h) = Utils.GetGameViewResolutionAsTuple();
Debug.Log($"GameViewResolution (Tuple): {w}x{h}");
}
GUILayout.Space(15);
}
}
注意点として、エディタスクリプトは任意の「Editor」フォルダ内に入れて使うか、プリプロセッサ(#if UNITY_EDITOR~#endif)で囲んで使う(通常はヒエラルキーでアタッチするスクリプトはプリプロセッサで囲み、エディタのみ使うものは Editor フォルダに入れるのが簡単)。これらは Unityエディタ上では使えるが、ランタイムでは使えない。あくまで開発支援用スクリプトとなる。
自由に改造して使うと良い。
(関連記事)
【Unity】【C#】画面解像度とアクペクト比(整数)を求める
【Unity】【C#】指定ワールド位置がカメラに映っているか調べる
【Unity】固定背景画像(2D)を表示する
【Unity】【エディタ拡張】フィールドの値などをインスペクタで横に並べて表示する 
2022/10/01 Sat [edit]
プロジェクトが大きくなってくるとデバッグが大変になってくるね。VRM Live Viewer は既に4周年を超えてしまったこともあって、とても巨大なシステムになってしまっている。Unity では Debug.Log を使うことも多いのだが、多くのオブジェクトがあると個々の状態が調べづらいので、最近はよくインスペクタをデバッグ代わりに使っている。
ただ独自クラス・構造体などを使うことも多いので、デフォルトだと全て縦に並んでしまうんだよね。なので Vector3 などの (x, y, z) のようにまとまってる要素は横に並べてすっきり表示したいことが多い。
そんな時は エディタ拡張の PropertyDrawer を使うと良い。簡単なものをメモとして載せておくので、色々応用すると良いだろう。

(※) Unity 2020.3.34f1 / Windows11(x64) で確認
●X, Y, Z 各軸の true / false 構造体の定義とインスペクタでの表示(PropertyDrawer)
using System;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Example //※名前は任意
{
//定義クラス・構造体
/// <summary>
/// X, Y, Z 各軸の true / false 構造体
/// </summary>
[Serializable]
public struct AxisBool
{
public bool x;
public bool y;
public bool z;
public AxisBool(bool x, bool y, bool z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
#if UNITY_EDITOR
//エディタ拡張(インスペクタ表示)
[CustomPropertyDrawer(typeof(AxisBool))]
public class AxisBoolDrawer : PropertyDrawer
{
static readonly GUIContent X_LABEL = new GUIContent("X");
static readonly GUIContent Y_LABEL = new GUIContent("Y");
static readonly GUIContent Z_LABEL = new GUIContent("Z");
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var xProperty = property.FindPropertyRelative("x");
var yProperty = property.FindPropertyRelative("y");
var zProperty = property.FindPropertyRelative("z");
//名前
label = EditorGUI.BeginProperty(position, label, property);
Rect contentPosition = EditorGUI.PrefixLabel(position, label);
//ラベル
contentPosition.width *= 1f / 3f; //3つ並べる場合 (n 個のとき、1 / n)
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = 15f; //ラベル幅(適当)
//各要素
EditorGUI.PropertyField(contentPosition, xProperty, X_LABEL);
contentPosition.x += contentPosition.width;
EditorGUI.PropertyField(contentPosition, yProperty, Y_LABEL);
contentPosition.x += contentPosition.width;
EditorGUI.PropertyField(contentPosition, zProperty, Z_LABEL);
EditorGUI.EndProperty();
}
}
#endif
}
ポイントは定義クラス・構造体用の PropertyDrawer を継承したクラスを作ることで([CustomPropertyDrawer] 属性も付ける)、これは以前に書いた「インスペクタで入力不可(Disable)な属性を作る」と同じである。要するに表示位置を計算して描くだけなので、定型処理(文)のように考えた方が楽だろう。
テストは適当に GameObject にアタッチしたスクリプトに、フィールドとして追加すれば良い(public または [SerializeField] 属性を付ける)。
ついでにスクショのもう1つの方も書いておくと、以下のようになる。
●X, Y, Z 各軸の Min~Max 構造体の定義とインスペクタでの表示(PropertyDrawer)
using System;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Example //※名前は任意
{
//定義クラス・構造体
/// <summary>
/// X, Y, Z 各軸の Min~Max 構造体
/// </summary>
[Serializable]
public struct RangeVector3
{
public float xMin;
public float xMax;
public float yMin;
public float yMax;
public float zMin;
public float zMax;
public RangeVector3(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax)
{
this.xMin = xMin;
this.xMax = xMax;
this.yMin = yMin;
this.yMax = yMax;
this.zMin = zMin;
this.zMax = zMax;
}
}
#if UNITY_EDITOR
//エディタ拡張(インスペクタ表示)
[CustomPropertyDrawer(typeof(RangeVector3))]
public class RangeVector3Drawer : PropertyDrawer
{
static readonly GUIContent X_MIN_LABEL = new GUIContent("X Min");
static readonly GUIContent X_MAX_LABEL = new GUIContent("X Max");
static readonly GUIContent Y_MIN_LABEL = new GUIContent("Y Min");
static readonly GUIContent Y_MAX_LABEL = new GUIContent("Y Max");
static readonly GUIContent Z_MIN_LABEL = new GUIContent("Z Min");
static readonly GUIContent Z_MAX_LABEL = new GUIContent("Z Max");
const float lineSpace = 2f; //行間
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight * 3 + lineSpace * 2;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var xMinProperty = property.FindPropertyRelative("xMin");
var xMaxProperty = property.FindPropertyRelative("xMax");
var yMinProperty = property.FindPropertyRelative("yMin");
var yMaxProperty = property.FindPropertyRelative("yMax");
var zMinProperty = property.FindPropertyRelative("zMin");
var zMaxProperty = property.FindPropertyRelative("zMax");
//名前
label = EditorGUI.BeginProperty(position, label, property);
Rect contentPosition = EditorGUI.PrefixLabel(position, label);
//ラベル
contentPosition.width *= 1f / 2f; //2つ並べる場合 (n 個のとき、1 / n)
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = 40f; //ラベル幅(適当)
//各要素
contentPosition.height = EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(contentPosition, xMinProperty, X_MIN_LABEL);
contentPosition.x += contentPosition.width;
EditorGUI.PropertyField(contentPosition, xMaxProperty, X_MAX_LABEL);
contentPosition.x -= contentPosition.width;;
contentPosition.y += EditorGUIUtility.singleLineHeight + lineSpace;
EditorGUI.PropertyField(contentPosition, yMinProperty, Y_MIN_LABEL);
contentPosition.x += contentPosition.width;
EditorGUI.PropertyField(contentPosition, yMaxProperty, Y_MAX_LABEL);
contentPosition.x -= contentPosition.width;;
contentPosition.y += EditorGUIUtility.singleLineHeight + lineSpace;
EditorGUI.PropertyField(contentPosition, zMinProperty, Z_MIN_LABEL);
contentPosition.x += contentPosition.width;
EditorGUI.PropertyField(contentPosition, zMaxProperty, Z_MAX_LABEL);
EditorGUI.EndProperty();
}
}
#endif
}
こちらも contentPosition を横・縦に移動して描いているだけと考えれば色々応用は利くだろう。日本語だとラベル幅からはみ出るかも知れないが(私は英語インターフェイスに慣れてしまってるので、日本語版は使ったことがない)、その辺はよしなに(笑)。
(参考)
・【Unity】最小と最大の値を管理する構造体を作りたいの
(関連記事)
【Unity】インスペクタで入力不可(Disable)な属性を作る
【Unity】インスペクタの表示項目を動的に変更する
【Unity】インスペクタの UnityEvent を並べ替え可能にする
【Unity】インスペクタの配列やリストを並べ替え可能にする
【Unity】インスペクタの値を保持したまま変数をリネームする
【Unity】独自のギズモ(Gizmo)を表示する
【Unity】【エディタ拡張】Project Settings (Graphics Settings) をスクリプトで変更する 
2022/02/20 Sun [edit]
う~む、Unity 標準の Fog (Light Settings にあるやつ) を実験してたんだけど、どうやら Android でビルドすると、アプリサイズが肥大化するみたいだな。3種類(Linear, Exponential, ExponentialSquared) 入れてみたら、200MB も増えた…。そしてスマホだとメモリー不足で落ちる…。|||orz
しかし、PC 版には入れたい(PC 版ではあまりサイズは増えない)。だけど Graphics Settings って、Shader stripping 以下の項目ってプラットフォームごとに設定できないんだよね。PC 版では Custom で 3種類(Linear, Exponential, ExponentialSquared) 入れて、Android 版では入れないようにしたい。でも毎回手動で設定するのは面倒くさい…。
Editor~系のクラスでできるのかな?と思ったけど、どうもできそうなのが見つからないので、ググってみたら、似たようなことをやってるのを見つけた。これを改造したら、どうやら上手く行くようだ。そのメモ。
(参考)
・Project Settings の「Disable Unity Audio」をスクリプトから操作する方法
(※) Unity 2020.3.26f1 / Windows11(x64) で確認
●Graphics Settings の Fog 設定をスクリプトで変更する (メニュー)
using System.Linq;
using UnityEngine;
using UnityEditor;
namespace Exsample
{
//※Editor フォルダに配置
public static partial class GraphicsSettingsEdit //※クラス名は任意
{
//フォグ設定をビルドに含める
[MenuItem("Tools/Include Fog in Build")]
private static void IncludeFogInBuild()
{
var path = "ProjectSettings/GraphicsSettings.asset";
var manager = AssetDatabase.LoadAllAssetsAtPath(path).FirstOrDefault();
var obj = new SerializedObject(manager);
var prop = obj.FindProperty("m_FogStripping");
prop.intValue = 1; //0: Automatic, 1: Custom
prop = obj.FindProperty("m_FogKeepLinear");
prop.boolValue = true;
prop = obj.FindProperty("m_FogKeepExp");
prop.boolValue = true;
prop = obj.FindProperty("m_FogKeepExp2");
prop.boolValue = true;
obj.ApplyModifiedProperties();
}
//フォグ設定をビルドから除外
[MenuItem("Tools/Exclude Fog in Build")]
private static void ExcludeFogInBuild()
{
var path = "ProjectSettings/GraphicsSettings.asset";
var manager = AssetDatabase.LoadAllAssetsAtPath(path).FirstOrDefault();
var obj = new SerializedObject(manager);
var prop = obj.FindProperty("m_FogStripping");
prop.intValue = 1; //0: Automatic, 1: Custom
prop = obj.FindProperty("m_FogKeepLinear");
prop.boolValue = false;
prop = obj.FindProperty("m_FogKeepExp");
prop.boolValue = false;
prop = obj.FindProperty("m_FogKeepExp2");
prop.boolValue = false;
obj.ApplyModifiedProperties();
}
}
}
これは Unity プロジェクトのルートにある ProjectSettings フォルダ内の GraphicsSettings.asset の内容を書き換えるものだ。各 ~.asset ファイルは YAML(?)なので、テキストエディタで開ける。"m_~" でプロパティ名で保存されているので、何でもできそうだ(名前がわからないのなら、一度エディタで変更して、差分を見ればわかる)。
ここでは余談だが、Automatic だと、エディタではオフで、ランタイムでオンに切り替えたりする使い方の場合、stripping されるのでビルドに含まれなくなってしまう。必ず Custom にして、使いたい FogMode をオンにしておく必要がある。

上記のスクリプトはメニューから変更するものだけど、これと以前作ったプラットフォーム切り替えのコールバックを合わせれば、自動で設定変更もできる。
・Unity2020 でプラットフォーム切り替えをすると、Run In Background が勝手にオフになってしまう
●プラットフォーム切り替え・ビルド開始時にフォグ設定を強制的に更新するスクリプト
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;
//※Editor フォルダに配置
public class EditorPlatformSetting : IActiveBuildTargetChanged, IPreprocessBuild //※クラス名は任意
{
public int callbackOrder => 0;
//ビルドターゲットを変更したときのコールバックハンドラ
public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget)
{
Debug.Log("BuildTarget is " + newTarget);
UpdateFogSettingsByPlatform(newTarget);
}
//ビルド開始するときのコールバックハンドラ
public void OnPreprocessBuild(BuildTarget target, string path)
{
UpdateFogSettingsByPlatform(target);
}
//プラットフォームにより、強制的にフォグ設定を更新する
void UpdateFogSettingsByPlatform(BuildTarget target)
{
switch (target)
{
//※必要なら、プラットフォームを追加する
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
IncludeFogInBuild(); //フォグをビルドに含める
break;
case BuildTarget.Android:
ExcludeFogInBuild(); //フォグをビルドから除外
break;
}
}
}
OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget) でプラットフォーム判別できるので、ここで IncludeFogInBuild() または ExcludeFogInBuild() を呼べば良いね。path と FindProperty() のプロパティ名を変えれば、色々自動化できそうだ。ただし、Unity はバージョンによって、たまにプロパティ名が変わるので、そこだけは注意だけどね。
(関連記事)
Unity】Unity2020 でプラットフォーム切り替えをすると、Run In Background が勝手にオフになってしまう
【Unity】【エディタ拡張】ヒエラルキー(シーン)の Image, RawImage に使われている画像(Texture)を検出するエディタ拡張(ツール) 
2020/11/11 Wed [edit]
1つのアプリの開発を長く続けていると「あれ?この画像もう使ってなかったような…?」なんてこと良くある。バージョンアップによって不要になった画像や、アイコン(UI)を変更したり、プロジェクト内には残ってるけど、実際のシーン(ヒエラルキー)上には使ってなかったり。だけど、いきなり削除してしまうと、万が一使ってるものがあったら、画像が抜けてしまう…。
そんなときに利用するツール。プロジェクトビューからツールに画像を指定して、検索ボタン(Search)を押せば、今開いているシーンの全ての Image, RawImage にセットされている画像と比較して、検出してくれる。
検索結果をクリックすれば、オブジェクトを選択してくれるし、検出後に [Select] ボタンを押せば、全てを選択してくれるので、画像を一気に入れ替えるなども簡単だ。
ここではツールのマニュアル的なものを書いておこう。
(※) Unity 2019.4.14f1 / Windows10(x64) で確認
■AttachedImageFinder のインポートと起動
パッケージのインポートダイアログでは、ツール本体(スクリプト)とテスト用のシーンが入っている。「_Test」以下はテスト用のサンプルシーンなので、ツールだけで良いなら、スクリプトだけでも良い。

ツール(スクリプト)をインポートしたら、「Tools」メニュー以下に「Attached Image Finder」が追加されるので、そこから起動しよう。

■AttachedImageFinder の使い方
「Tools」メニューから起動したら、「検索画像(Texture)」に画像をセットしよう。プロジェクトビューからドロップしても良いし、ボックスの一番右にある◎を押して、画像を選択しても良い。

デフォルトでは(None のとき)ヒエラルキーの全てのオブジェクトから検索するが、範囲を絞り込みたいときは、検索開始となる Transform をヒエラルキーからドロップしてセットしよう。セットした場合はその位置以下の階層からしか検出しなくなる。
「検索オプション」の Image, RawImage はチェックを付けたものにセットされている画像から検出する。


検索後は結果をクリックするか、「Select」ボタンを押せば、結果全てを選択できる。

ちなみに、ヒエラルキーの階層を一気に展開するには、親を選択した後で、[Alt] + [→] (開く), [Alt] + [←] (閉じる) のショートカットを使うと便利だ。
あとは画像を入れ替えたり、削除したりと自分の好きにすれば良い。
使い方は難しくないだろう。
AttachedImageFinder はスクリプトだけでできているので、自由にコピペして新しいツールでも作ってみるのも良いだろう。そのほとんどの機能が前回までの Transform 系の便利メソッドで作られている。誰かの役に立つのであれば、公開した甲斐があるというものである(笑)。
(関連記事)
【Unity】【C#】シーン(ヒエラルキー)のルートにある Transform を全て取得する(非アクティブも含む)
【Unity】【C#】非アクティブも含めて、全ての GameObject からコンポーネントを取得する
【Unity】【C#】Transfrom (GameObject) のパス名を取得する
【Unity】【C#】非アクティブも含めて、Transform (GameObject) をパス名で取得する
【Unity】【C#】ヒエラルキー(シーン)の全てのオブジェクト(Transform)をスキャンして処理をする
【Unity】【C#】EventSystem を InputSystem 用に置き換えると、スクロールビュー等の移動が速過ぎる
- 関連記事
category: Unity
thread: ゲーム開発
janre: コンピュータ
tag: Unityライブラリ Unityプラグイン エディタ拡張 Transform FantomPlugin【Unity】【エディタ拡張】インスペクタの UnityEvent を並べ替え可能にする 
2020/04/27 Mon [edit]
前回「インスペクタの配列やリストを並べ替え」を紹介したが、UnityEvent も並べ替えたいときもよくあるだろう。これもとても導入・利用が簡単なものがあるので、ついでに紹介しておこう。
・EasyEventEditor (MIT 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() から呼んでも良い)、コールバックの発火はインスペクタで登録した上→下の順になる。試してみよう。
●並べ替え前
Fuga
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 でのコールバック実装方法とインスペクタでの登録