うにてぃブログ

UnityやUnreal Engineの記事を書いていきます

【Unity】自作 VisualElement に独自の変数を追加する

UIBuilder では VisualElement に独自の変数があった場合は Inspector に表示される

Label の場合は Text の領域が表示され、変更することで表示される文字も変更される

f:id:hacchi_man:20201031201241p:plain:w450

Name から Focusable までは VisualElement で定義されている変数なので、どの要素に対してでも表示される

f:id:hacchi_man:20201031202645p:plain:w300

独自変数の領域作成

パラメータを入力するためには UxmlTraits を内部クラスとして作成し
UxmlStringAttributeDescription 等 の UxmlAttributeDescription が必要になります

現状対応している UxmlAttributeDescription には以下のものがあり、必要に応じて適切なクラスを利用します

クラス
UxmlStringAttributeDescription string
UxmlDoubleAttributeDescription double
UxmlIntAttributeDescription int
UxmlLongAttributeDescription long
UxmlBoolAttributeDescription bool
UxmlColorAttributeDescription color
UxmlTypeAttributeDescription Type
UxmlEnumAttributeDescription enum

独自変数を持つ VisualElement

UxmlTraits に UxmlStringAttributeDescription を追加した場合は下記になります

f:id:hacchi_man:20201031203326p:plain:w300

using UnityEngine.UIElements;
 
namespace Sample
{
    public class SampleElement : VisualElement
    {
        public new class UxmlFactory : UxmlFactory<SampleElement, UxmlTraits>
        {
        }
 
        public new class UxmlTraits : VisualElement.UxmlTraits
        {
            UxmlStringAttributeDescription _text = new UxmlStringAttributeDescription {name = "str-value"};
 
            public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
            {
                var e = ve as SampleElement;
                e._label.text = _text.GetValueFromBag(bag, cc);

                base.Init(ve, bag, cc);
            }
        }
 
        private Label _label;
 
        public SampleElement()
        {
            _label = new Label();
            Add(_label);
        }
    }
}

しかし、UIBuilder に入力欄が表示され、ラベルの表示も変更されますが
別の要素を選択して戻ってくると入力値が入っていません

f:id:hacchi_man:20201031203944g:plain:w600

一応 uxml には値が入ってるので、動作させるときは問題ないと思われますが気になるので対応策を考えます

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
    <Sample.SampleElement str-value="SampleLabel" />
</ui:UXML>

独自変数の値を反映させる

値を反映するには UxmlAttributeDescription.name と同じ変数が定義されている必要があります

今回であれば name が str-value なので

// strValue, strvalue でも有効
private string StrValue;

の定義が必要です
※ 恐らくname から - を消して、大文字小文字関係無く一致すれば問題無さそう

今回に関してはラベルの表示を変更するため、正しくは下記になります

private string Strvalue
{
    get => _label.text;
    set => _label.text = value;
}