バージョン: 2021.3 以降
この例では、バインドされたシリアル化されたオブジェクトのいずれかのプロパティが変更されたときに、コールバックを受け取る方法を示します。
この例では、2 つのフィールドを持つカスタム Inspector を作成します。フィールドの値が特定の範囲外の場合、ユーザーに警告を発します。
この例で作成するすべてのファイルは、GitHub リポジトリ にあります。
This guide is for developers familiar with the Unity Editor, UI Toolkit, and C# scripting. You are recommended to have a basic understanding of the following:
C# スクリプトを作成し、2 つのプロパティ m_BaseDamage
と m_HardModeModifier
を持つ MonoBehaviour
として Weapon
クラスを定義します。
Unity で任意のテンプレートでプロジェクトを作成します。
Project ウィンドウに、callback-any-SerializedProperty-changes
という名前のフォルダーを作成し、ファイルを保存してください。
Weapon.cs
という名の C# スクリプトを作成し、そのコンテンツを以下と置き換えます。
using UnityEngine;
namespace UIToolkitExamples
{
public class Weapon : MonoBehaviour
{
public const float maxDamage = 9999f;
[SerializeField]
float m_BaseDamage;
[SerializeField]
float m_HardModeModifier;
public float GetDamage(bool hardMode)
{
return hardMode ? m_BaseDamage * m_HardModeModifier : m_BaseDamage;
}
}
}
Weapon
のカスタム Inspector を定義する C# スクリプトを作成し、 TrackSerializedObjectValue()
メソッドを使用して m_BaseDamage
プロパティと m_HardModeModifier
プロパティの変更を確認します。
callback-any-SerializedProperty-changes フォルダー内に、Editor
という名前のフォルダーを作成します。
Editor フォルダーに、WeaponCustomEditor.cs
という名の C# スクリプトを作成し、そのコンテンツを以下と置き換えます。
using UnityEngine;
using UnityEditor;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UIToolkitExamples
{
[CustomEditor(typeof(Weapon))]
public class WeaponCustomEditor : Editor
{
// This is text used for the warning labels.
const string k_NegativeWarningText =
"This weapon has a negative final damage on at least 1 difficulty level.";
static readonly string k_DamageCapWarningText =
"This weapon has an excessive final damage that is capped to " + Weapon.maxDamage +
" on at least 1 difficulty level.";
// These are labels to warn users about negative damage and excessive damage.
Label m_NegativeWarning, m_DamageCapWarning;
public override VisualElement CreateInspectorGUI()
{
VisualElement root = new();
// Create FloatFields for serialized properties.
var baseDamageField = new FloatField("Base Damage") { bindingPath = "m_BaseDamage" };
var modifierField = new FloatField("Hard Mode Modifier") { bindingPath = "m_HardModeModifier" };
root.Add(baseDamageField);
root.Add(modifierField);
// Create warning labels and style them so they stand out.
var warnings = new VisualElement();
m_NegativeWarning = new(k_NegativeWarningText);
m_DamageCapWarning = new(k_DamageCapWarningText);
warnings.style.color = Color.red;
warnings.style.unityFontStyleAndWeight = FontStyle.Bold;
warnings.Add(m_NegativeWarning);
warnings.Add(m_DamageCapWarning);
root.Add(warnings);
// Determine whether to show the warnings at the start.
CheckForWarnings(serializedObject);
// Whenever any serialized property on this serialized object changes its value, call CheckForWarnings.
root.TrackSerializedObjectValue(serializedObject, CheckForWarnings);
return root;
}
// Check the current values of the serialized properties to either display or hide the warnings.
void CheckForWarnings(SerializedObject serializedObject)
{
// For each possible damage values of the weapon, determine whether it's negative and whether it's above the
// maximum damage value.
var weapon = serializedObject.targetObject as Weapon;
var damages = new float[] { weapon.GetDamage(true), weapon.GetDamage(false) };
var foundNegativeDamage = false;
var foundCappedDamage = false;
foreach (var damage in damages)
{
foundNegativeDamage = foundNegativeDamage || damage < 0;
foundCappedDamage = foundCappedDamage || damage > Weapon.maxDamage;
}
// Display or hide warnings depending on the values of the damages.
m_NegativeWarning.style.display = foundNegativeDamage ? DisplayStyle.Flex : DisplayStyle.None;
m_DamageCapWarning.style.display = foundCappedDamage ? DisplayStyle.Flex : DisplayStyle.None;
}
}
}
シーンで空のゲームオブジェクトを作成します。
ゲームオブジェクトを選択します
Inspector に Weapon コンポーネントを加えます。
Weapon コンポーネントで、フィールドの値を変更します。