バージョン: 2022.3+
MonoBehaviour と ScriptableObject に対してはデフォルトインスペクターがありますが、独自のクラス用にカスタムインスペクターの作成が求められる場合もあります。カスタムインスペクターは、以下の操作に役立ちます。
この例では、MonoBehaviour クラス用にカスタムインスペクターを作成します。C# スクリプトと UI Builder の両方を使用して UI を作成します。カスタムインスペクターには、カスタムプロパティドロワーもあります。
カスタムインスペクターには、メーカー、製造年、色、タイヤのリストなど、Car クラスのプロパティが表示されます。インスペクターは PropertyField コントロールを使用して Car クラスのプロパティを表示します。また、カスタムプロパティドロワーを使用して Tire クラスのプロパティを表示します。
この例で作成する完成したファイルは、こちらの GitHub リポジトリにあります。
このガイドは、Unity エディター、UI Toolkit、および C# スクリプトに精通している開発者を対象としています。始める前に、以下の点を理解しておいてください。
カスタムインスペクターを作成するには、最初に MonoBehaviour から継承するカスタムクラスを定義します。カスタムクラスは、いくつかのプロパティを持つ単純な car を表します。
Unity で、任意のテンプレートでプロジェクトを作成します。
Project ウィンドウに、create-a-custom-inspector という名前のフォルダーを作成し、すべてのファイルを保存します。
以下のコンテンツで Car.cs という名前の C# スクリプトを作成します。
using UnityEngine;
public class Car : MonoBehaviour
{
public string m_Make = "Toyota";
public int m_YearBuilt = 1980;
public Color m_Color = Color.black;
}
シーン内に新しいゲームオブジェクトを作成し、Car スクリプトコンポーネントをそれにアタッチします。
任意のシリアライズされたオブジェクトのカスタムインスペクターを作成するには、Editor 基本クラスから派生したクラスを作成し、CustomEditor 属性をそのクラスに追加する必要があります。この属性によって、Unity はこのカスタムインスペクターがどのクラスを表しているのかを知ることができます。
ノート: カスタムインスペクタースクリプトは、Editor フォルダーまたはエディター専用のアセンブリ定義内に置く必要があります。これは、カスタムインスペクターの作成に不可欠な UnityEditor 名前空間に、これらの領域外からアクセスできないためです。これに従わずにスタンドアロンビルドを作成しようとすると、ビルドプロセスは失敗します。
create-a-custom-inspector フォルダー内に Editor という名前のフォルダーを作成します。
Editor フォルダー内に以下のコンテンツを含む Car_Inspector.cs という名前の C# スクリプトを作成します。
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
[CustomEditor(typeof(Car))]
public class Car_Inspector : Editor
{
}
Car コンポーネントがアタッチされているゲームオブジェクトを選択します。デフォルトインスペクターが表示されます。
デフォルトインスペクターを置き換えるには、Car_Inspector クラス内に、CreateInspectorGUI() をオーバーライドし、UI を含む新しいビジュアル要素を返す、以下のコードを追加します。
public override VisualElement CreateInspectorGUI()
{
// Create a new VisualElement to be the root of our Inspector UI.
VisualElement myInspector = new VisualElement();
// Add a simple label.
myInspector.Add(new Label("This is a custom Inspector"));
// Return the finished Inspector UI.
return myInspector;
}
Car コンポーネントがアタッチされているゲームオブジェクトを選択します。このインスペクターは、デフォルトインスペクターの代わりにラベル This is a custom Inspector を表示します。
UI Builder でカスタムインスペクター UI を作成し、C# スクリプトを使用して UXML ファイルから UI のロードとインスタンス化ができます。
UI Builder を開くには、Window > UI Toolkit > UI Builder を選択します。
File > **New ** を選択して、新しいビジュアルツリーアセットを作成します。
UI Builder でエディター専用コントロールを有効にするには、Hierarchy ビューで <unsaved file>*.uxml を選択し、Editor Extension Authoring チェックボックスにチェックを入れます。
ラベルコントロールを Library から Hierarchy にドラッグします。これにより、ビジュアルツリーにラベルコントコントロールが追加されます。
ラベルコントロールの Inspector パネルで、ラベルのテキストを更新します。
File > Save を選択し、ビジュアルツリーを Car_Inspector_UXML.uxml として Assets/create-a-custom-inspector フォルダーに保存します。
作成した UXML ファイルをカスタムインスペクター内で使用するには、ファイルをカスタムインスペクターに割り当て、CreateInspectorGUI() 関数内でロードして複製し、ビジュアルツリーに追加する必要があります。これを行うには、CloneTree メソッドを使用します。作成された要素の親として動作するように、任意の VisualElement をパラメーターとして渡すことができます。
Car_Inspector.cs 内で、スクリプトで VisualTreeAsset のパブリック変数を作成し、それに Car_Inspector_UXML.uxml を割り当てます。
public VisualTreeAsset m_InspectorXML;
CreateInspectorGUI() メソッドを以下のように更新します。
public override VisualElement CreateInspectorGUI()
{
// Create a new VisualElement to be the root of our Inspector UI.
VisualElement myInspector = new VisualElement();
// Add a simple label.
myInspector.Add(new Label("This is a custom Inspector"));
// Load the UXML file.
m_InspectorXML= AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/create-a-custom-inspector/Car_Inspector_UXML.uxml");
// Instantiate the UXML.
myInspector = m_InspectorXML.Instantiate();
// Return the finished Inspector UI.
return myInspector;
}
Car コンポーネントがアタッチされているゲームオブジェクトを選択します。car コンポーネントの Inspector に、スクリプトによるものと UI Builder/UXML によるものの 2 つのラベルが表示されます。
このカスタムインスペクターは、Car クラスのすべてのプロパティを表示します。ユーザーが UI コントロールのいずれかを変更する場合、Car クラスのインスタンス内の値も変更します。そのために、ビジュアルツリーに UI コントロールを追加し、クラスの個々のプロパティにバインドします。
コントロールをシリアル化されたプロパティにバインドするには、コントロールの binding-path フィールドにプロパティを割り当てます。カスタムインスペクターの作成時、バインディングは自動的に行われます。CreateInspectorGUI() は、ビジュアルツリーを返した後に暗示的にバインドします。詳細は、SerializedObject データバインディングを参照してください。
Car_Inspector_UXML.uxml をダブルクリックして、UI Builder で開きます。
TextField コントロールを追加します。
TextField の Inspector パネルで、ラベルテキストを Make of the car に設定します。
バインディングパスを m_Make に設定します。
スタイルクラスリストにスタイルクラス unity-base-field__aligned を追加し、テキストフィールドが Inspector ウィンドウの他のフィールドと揃うようにします。詳細については、BaseField を参照してください。
UI Builder で File > Save を選択します。
Car コンポーネントがアタッチされているゲームオブジェクトを選択します。car コンポーネントの Inspector に Make of the car テキストフィールドが表示されます。テキストフィールドは、Car クラスの m_Make プロパティにバインドされます。
Car クラスのプロパティを表示するには、各フィールドのコントロールを追加します。また、コントロールはプロパティのタイプと一致する必要があります。例えば、int は Integer フィールドまたは Integer スライダーにバインドする必要があります。
プロパティタイプに基づいて特定のコントロールを追加する代わりに、汎用の PropertyField コントロールを使用することができます。このコントロールは、ほとんどのタイプのシリアル化されたプロパティで動作し、このプロパティタイプのデフォルトインスペクター UI を生成します。
PropertyField の利点は、スクリプト内部で変数の型を変更すると、Inspector の UI が自動的に調整されることです。ただし、UI Builder 内でコントロールのプレビューを取得することはできません。これは、ビジュアルツリーがシリアル化されたオブジェクトにバインドされるまでコントロールの種類がわからないためです。
Car_Inspector_UXML.uxml をダブルクリックして、UI Builder で開きます。
Car クラスの m_YearBuilt プロパティの PropertyField コントロールを追加し、バインディングパスとラベルテキストを設定します。
スタイルクラス unity-base-field__aligned をスタイルクラスリストに追加します。
Car クラスの m_Color プロパティの PropertyField コントロールを追加し、バインディングパスとラベルテキストを設定します。
スタイルクラス unity-base-field__aligned をスタイルクラスリストに追加します。
UI Builder で File > Save を選択します。
Car コンポーネントを持つゲームオブジェクトを選択します。これで、car コンポーネントの Inspector に、Year Built と Paint Color のプロパティフィールドが表示されるようになります。
カスタムプロパティドロワーは、カスタムの serializable クラスのためのカスタムインスペクター UI です。その serializable クラスが他のシリアライズされたオブジェクトの一部である場合、カスタム UI は Inspector にそのプロパティを表示します。UI Toolkit では、PropertyField コントロールは、フィールドのカスタムプロパティドロワーが存在する場合、それを表示します。
create-a-custom-inspector フォルダーに、以下のコンテンツで Tire.cs という名前の新しいスクリプトを作成します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Tire
{
public float m_AirPressure = 21.5f;
public int m_ProfileDepth = 4;
}
Car.cs 内で Car クラスにリスト Tire を追加します。完成した Car.cs は以下のようになります。
using UnityEngine;
public class Car : MonoBehaviour
{
public string m_Make = "Toyota";
public int m_YearBuilt = 1980;
public Color m_Color = Color.black;
// This car has four tires.
public Tire[] m_Tires = new Tire[4];
}
PropertyField コントロールは、すべての標準的なプロパティタイプで動作し、カスタムのシリアライズ可能なクラスと配列もサポートします。車のタイヤのプロパティを表示するには、別の PropertyField を Car_Inspector_UXML.uxml に追加して m_Tires にバインドします。完成した Car_Inspector_UXML.uxml は以下のようになります。
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="True">
<ui:TextField picking-mode="Ignore" label="Make of the car" value="filler text" binding-path="m_Make" class="unity-base-field__aligned" />
<uie:PropertyField binding-path="m_YearBuilt" label="Year Built" class="unity-base-field__aligned" />
<uie:PropertyField binding-path="m_Color" label="Paint Color" class="unity-base-field__aligned" />
<uie:PropertyField label="Tires" binding-path="m_Tires" class="unity-base-field__aligned" />
</ui:UXML>
Car コンポーネントを持つゲームオブジェクトを選択します。car コンポーネントの Inspector に Tires プロパティフィールドが表示されます。
カスタムプロパティードロワーを作成し、リスト内の個々の Tire 要素の外観をカスタマイズすることができます。カスタムプロパティドロワーは、Editor 基本クラスから派生する代わりに、PropertyDrawer クラスから派生します。
C# スクリプトまたは UXML を使用して、プロパティの UI を作成できます。この例では、C# スクリプトを使用してカスタム UI を作成します。カスタムプロパティの UI を作成するには、CreatePropertyGUI メソッドをオーバーライドします。
Editor フォルダーに、以下のコンテンツで Tire_PropertyDrawer.cs という名前の新しいスクリプトを作成します。
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
[CustomPropertyDrawer(typeof(Tire))]
public class Tire_PropertyDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
// Create drawer UI using C#.
var popup = new UnityEngine.UIElements.PopupWindow();
popup.text = "Tire Details";
popup.Add(new PropertyField(property.FindPropertyRelative("m_AirPressure"), "Air Pressure (psi)"));
popup.Add(new PropertyField(property.FindPropertyRelative("m_ProfileDepth"), "Profile Depth (mm)"));
// Return the finished UI.
return popup;
}
}
Car コンポーネントを持つゲームオブジェクトを選択します。car コンポーネントの Inspector に、Tires プロパティフィールドとカスタムプロパティドロワーが表示されます。
デフォルトインスペクター UI を表示するフォールドアウトコントロールを作成します。フォールドアウトコントロールにデフォルトインスペクター UI を添付するには、フォールドアウトへの参照を取得する必要があります。フォールドアウトのビジュアル要素は、UQuery を使用して Inspector のビジュアルツリーから取得し、InspectorElement クラスの FillDefaultInspector メソッドを使用することで、デフォルトインスペクター UI をフォールドアウトコントロールに設定できます。
Car_Inspector_UXML.uxml ファイルをダブルクリックして、UI Builder で開きます。
フォールドアウトコントロールを UI に追加し、Default_Inspector という名前を付けて、ラベルテキストを設定します。
Car_Inspector.cs ファイルで、CreateInspectorGUI() メソッドを更新して Default_Inspector フォールドアウトへのリファレンスを取得し、デフォルトインスペクター UI を設定します。完成した Car_Inspector.cs は以下のようになります。
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
[CustomEditor(typeof(Car))]
public class Car_Inspector : Editor
{
public VisualTreeAsset m_InspectorUXML;
public override VisualElement CreateInspectorGUI()
{
// Create a new VisualElement to be the root of our Inspector UI.
VisualElement myInspector = new VisualElement();
// Add a simple label.
myInspector.Add(new Label("This is a custom Inspector"));
// Load the UXML file and clone its tree into the inspector.
if (m_InspectorUXML != null)
{
VisualElement uxmlContent = m_InspectorUXML.CloneTree();
myInspector.Add(uxmlContent);
}
// Return the finished Inspector UI.
return myInspector;
}
}
Car コンポーネントを持つゲームオブジェクトを選択します。car コンポーネントの Inspector に、デフォルトインスペクター UI を持つ Default Inspector フォールドアウトが表示されます。