主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ
書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。
2022/02/18
前回はコールバックを作成しましたが、今回は独自のコントロールを作ってみましょう!
ということで、早速 UXML と C# スクリプトを書きます。
たとえば、こんな感じのメッセージボックスを作りたい場合は、
以下のような 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:VisualElement class="flex flex-row border-2 border-slate-400 rounded-md p-2 my-2 items-center">
<engine:VisualElement class="flex justify-center items-center">
<engine:Image name="icon" class="w-10 h-10 min-h-full" />
</engine:VisualElement>
<engine:VisualElement class="flex-grow ml-2">
<engine:TextElement name="text" class="text-lg" />
</engine:VisualElement>
</engine:VisualElement>
</engine:UXML>
そして、これの icon
と text
部分を、親コンポーネントから受け取る値だったとします。
その場合、次のような C# スクリプトを記述します。
// ------------------------------------------------------------------------------------------
// Copyright (c) Natsuneko. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
// ------------------------------------------------------------------------------------------
using System.Collections.Generic;
using NatsunekoLaboratory.VRAvatarToolkit.Enums;
using NatsunekoLaboratory.VRAvatarToolkit.Extensions;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace NatsunekoLaboratory.VRAvatarToolkit.Controls
{
public class MessageBox : VisualElement
{
private readonly Image _icon;
private readonly TextElement _text;
public MessageBoxIcon Icon
{
set => _icon.style.backgroundImage = new StyleBackground(Background.FromTexture2D(EditorGUIUtility.Load(value.ToResourceString()) as Texture2D));
}
public string Text
{
get => _text.text;
set => _text.text = value;
}
public MessageBox()
{
// UXML / USS 読み込み部分は省略
_icon = this.Q<Image>("icon");
_text = this.Q<TextElement>("text");
}
public new class UxmlFactory : UxmlFactory<MessageBox, UxmlTraits> { }
public new class UxmlTraits : VisualElement.UxmlTraits
{
private readonly UxmlEnumAttributeDescription<MessageBoxIcon> _icon = new UxmlEnumAttributeDescription<MessageBoxIcon> { name = "icon", defaultValue = MessageBoxIcon.Info };
private readonly UxmlStringAttributeDescription _text = new UxmlStringAttributeDescription { name = "text", defaultValue = "" };
public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
{
get { yield break; }
}
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
((MessageBox)ve).Text = _text.GetValueFromBag(bag, cc);
((MessageBox)ve).Icon = _icon.GetValueFromBag(bag, cc);
}
}
}
}
該当コントロールのクラス実装のインナークラスとして、 UxmlTraits
みたいな感じで作ってあげると、バインディングされた値を受け取ることが出来ます。
最後に、 Init
メソッド経由で受け取れば、初期値がバインドされます。
2回目以降は普通に C# スクリプトからプロパティ経由でアクセス可能なので、特に実装は必要ありません。
ということで、今日のメモでした!