C# + UXML でエディター拡張を書いている際、 Binding 中の変数に対して、値が代入されるタイミングである処理を呼びたい、みたいなことはあると思うんですが、その方法の紹介です。
といっても Unity 2019 と 2020 では微妙にやり方が変わっているので、今回は Unity 2019 版でのお話。
まず、以下のような UXML があるとします。
<?xml version="1.0" encoding="utf-8" ?> <engine:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:engine="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" xsi:noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" > <engine:ScrollView class="min-h-full"> <engine:VisualElement class="container mx-auto my-4"> <engine:VisualElement class="my-2"> <engine:TextElement text="アバター着せ替えエディター" class="text-2xl mb-2" /> <engine:TextElement text="衣装を着せたいアバターと対応している衣装、アクセサリーなどを簡単に着せ替え、調節することが出来ます。" class="text-lg" /> </engine:VisualElement> <engine:VisualElement class="my-2"> <editor:PropertyField name="_avatar" label="アバター" /> </engine:VisualElement> </engine:VisualElement> </engine:ScrollView> </engine:UXML>
この場合、 _avatar
に値が Binding されると考えて、この値が変わったタイミングで、何らかのバリデーションをしたいとします。
その場合は、このように書くことで出来ます。
private SerializedObject _so; private void CreateGUI() { // 省略 var element = rootVisualElement.Q<PropertyField>("_avatar"); element.BindProperty(_so.FindProperty("_avatar")); element.RegisterCallback<ChangeEvent<Object>>(w => { /* ここに処理を入れる */}); }
このとき、 ChangeEvent
の Generics に渡す型パラメータは UnityEngine.Object
である必要があります。
他の型を指定するとコールバックは呼ばれることはありませんでした。
ちなみに、 IntField
とかの場合は、 RegisterValueChangedCallback
を使うことで、同様のことが出来ます。
ということで、今日のメモでした。