Version: 2022.3
言語: 日本語
2 つの属性を持つカスタムコントロールの作成
バインド可能なカスタムコントロールの作成

スライドトグルカスタムコントロールの作成

バージョン: 2021.3 以降

この例では、“スイッチのような” トグルを作成する方法を説明します。

例の概要

この例では、マウス、キーボード、ゲームパッド、その他のデバイスでユーザーが切り替えできるトグルというカスタムコントロールを作成します。このコントロールには、トグルが何を表しているかを説明するラベルも設定します。

この例で作成するすべてのファイルは、GitHub リポジトリ にあります。

要件

このガイドは、Unity エディター、UI Toolkit、および C# スクリプトに精通している開発者を対象としています。始める前に、以下をよく理解してください。

スライドトグルの作成とスタイル設定

C# スクリプトでスライドトグルのクラスを作成し、USS ファイルでスタイルを設定します。

  1. 3D テンプレートで Unity プロジェクトを作成します。この例では、3D テンプレートの方が高い視覚効果を得られます。ただし、どのテンプレートを使っても構いません。

  2. ファイルを保存するために slide-toggle という名前のフォルダーを作成します。

  3. slide-toggle フォルダーに、SlideToggle.cs という名前の C# スクリプトを作成します。

  4. テキストエディターで SlideToggle.cs スクリプトを開き、そのコンテンツを下のコードに置き換えます。

    using UnityEngine;
    using UnityEngine.UIElements;
    
    namespace MyUILibrary
    {
        // Derives from BaseField<bool> base class. Represents a container for its input part.
        public class SlideToggle : BaseField<bool>
        {
            public new class UxmlFactory : UxmlFactory<SlideToggle, UxmlTraits> { }
    
            public new class UxmlTraits : BaseFieldTraits<bool, UxmlBoolAttributeDescription> { }
    
            // In the spirit of the BEM standard, the SlideToggle has its own block class and two element classes. It also
            // has a class that represents the enabled state of the toggle.
            public static readonly new string ussClassName = "slide-toggle";
            public static readonly new string inputUssClassName = "slide-toggle__input";
            public static readonly string inputKnobUssClassName = "slide-toggle__input-knob";
            public static readonly string inputCheckedUssClassName = "slide-toggle__input--checked";
    
            VisualElement m_Input;
            VisualElement m_Knob;
    
            // Custom controls need a default constructor. This default constructor calls the other constructor in this
            // class.
            public SlideToggle() : this(null) { }
    
            // This constructor allows users to set the contents of the label.
            public SlideToggle(string label) : base(label, null)
            {
                // Style the control overall.
                AddToClassList(ussClassName);
    
                // Get the BaseField's visual input element and use it as the background of the slide.
                m_Input = this.Q(className: BaseField<bool>.inputUssClassName);
                m_Input.AddToClassList(inputUssClassName);
                Add(m_Input);
    
                // Create a "knob" child element for the background to represent the actual slide of the toggle.
                m_Knob = new();
                m_Knob.AddToClassList(inputKnobUssClassName);
                m_Input.Add(m_Knob);
    
                // There are three main ways to activate or deactivate the SlideToggle. All three event handlers use the
                // static function pattern described in the Custom control best practices.
    
                // ClickEvent fires when a sequence of pointer down and pointer up actions occurs.
                RegisterCallback<ClickEvent>(evt => OnClick(evt));
                // KeydownEvent fires when the field has focus and a user presses a key.
                RegisterCallback<KeyDownEvent>(evt => OnKeydownEvent(evt));
                // NavigationSubmitEvent detects input from keyboards, gamepads, or other devices at runtime.
                RegisterCallback<NavigationSubmitEvent>(evt => OnSubmit(evt));
            }
    
            static void OnClick(ClickEvent evt)
            {
                var slideToggle = evt.currentTarget as SlideToggle;
                slideToggle.ToggleValue();
    
                evt.StopPropagation();
            }
    
            static void OnSubmit(NavigationSubmitEvent evt)
            {
                var slideToggle = evt.currentTarget as SlideToggle;
                slideToggle.ToggleValue();
    
                evt.StopPropagation();
            }
    
            static void OnKeydownEvent(KeyDownEvent evt)
            {
                var slideToggle = evt.currentTarget as SlideToggle;
    
                // NavigationSubmitEvent event already covers keydown events at runtime, so this method shouldn't handle
                // them.
                if (slideToggle.panel?.contextType == ContextType.Player)
                    return;
    
                // Toggle the value only when the user presses Enter, Return, or Space.
                if (evt.keyCode == KeyCode.KeypadEnter || evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.Space)
                {
                    slideToggle.ToggleValue();
                    evt.StopPropagation();
                }
            }
    
            // All three callbacks call this method.
            void ToggleValue()
            {
                value = !value;
            }
    
            // Because ToggleValue() sets the value property, the BaseField class dispatches a ChangeEvent. This results in a
            // call to SetValueWithoutNotify(). This example uses it to style the toggle based on whether it's currently
            // enabled.
            public override void SetValueWithoutNotify(bool newValue)
            {
                base.SetValueWithoutNotify(newValue);
    
                //This line of code styles the input element to look enabled or disabled.
                m_Input.EnableInClassList(inputCheckedUssClassName, newValue);
            }
        }
    }
    
  5. slide-toggle フォルダーに、SlideToggle.uss という名の USS ファイルを作成します。

  6. SlideToggle.uss をテキストエディターで開き、そのコンテンツを以下のように置き換えます。`

    .slide-toggle__input {
        background-color: var(--unity-colors-slider_groove-background);
        max-width: 25px;
        border-top-left-radius: 8px;
        border-bottom-left-radius: 8px;
        border-top-right-radius: 8px;
        border-bottom-right-radius: 8px;
        overflow: visible;
        border-left-width: 1px;
        border-right-width: 1px;
        border-top-width: 1px;
        border-bottom-width: 1px;
        border-right-color: var(--unity-colors-slider_thumb-border);
        border-top-color: var(--unity-colors-slider_thumb-border);
        border-bottom-color: var(--unity-colors-slider_thumb-border);
        max-height: 16px;
        margin-top: 10px;
        border-left-color: var(--unity-colors-slider_thumb-border);
        transition-property: background-color;
        transition-duration: 0.5s;
    }
    
    .slide-toggle__input-knob {
        height: 16px;
        width: 16px;
        background-color: var(--unity-colors-slider_thumb-background);
        position: absolute;
        border-top-left-radius: 25px;
        border-bottom-left-radius: 25px;
        border-top-right-radius: 25px;
        border-bottom-right-radius: 25px;
        top: -1px;
        transition-property: translate, background-color;
        transition-duration: 0.5s, 0.5s;
        translate: -1px 0;
        border-left-width: 1px;
        border-right-width: 1px;
        border-top-width: 1px;
        border-bottom-width: 1px;
        border-left-color: var(--unity-colors-slider_thumb-border);
        border-right-color: var(--unity-colors-slider_thumb-border);
        border-top-color: var(--unity-colors-slider_thumb-border);
        border-bottom-color: var(--unity-colors-slider_thumb-border);
    }
    
    .slide-toggle__input--checked {
        background-color: rgb(0, 156, 10);
    }
    
    .slide-toggle__input--checked > .slide-toggle__input-knob {
        translate: 8px 0;
    }
    
    .slide-toggle:focus .slide-toggle__input-knob {
        border-left-width: 1px;
        border-right-width: 1px;
        border-top-width: 1px;
        border-bottom-width: 1px;
        border-left-color: var(--unity-colors-input_field-border-focus);
        border-right-color: var(--unity-colors-input_field-border-focus);
        border-top-color: var(--unity-colors-input_field-border-focus);
        border-bottom-color: var(--unity-colors-input_field-border-focus);
    }
    

UI Builder を使って UXML ファイルへスライドトグルを追加する

  1. slide-toggle フォルダーに、SlideToggleUsage.uxml という名前の UI ドキュメントを作成します。
  2. UI Builder で SlideToggleUsage.uxml を開きます。
  3. UI Builder で、Library > Project > MyUILibrary を選択します。
  4. SlideToggleHierarchy ウィンドウにドラッグします。
  5. Inspector で、Label にトグルのラベルテキストを入力します。
  6. StyleSheets セクションに、既存の USS として SlideToggle.uss を加えます。
  7. UI Builder を保存して終了します。

スライドトグルのテスト

  1. サンプルシーンで、UI Document ゲームオブジェクトを作成します。
  2. UI Document を選択し、SlideToggleUsage.uxmlInspectorSource Asset フィールドにドラッグします。
  3. 再生モードにします。トグルをクリックする、Enter キーを押す、Return キーを押す、または、Space キーを押す動作を行うと、トグルを前後に切り替えることができます。

その他の参考資料

2 つの属性を持つカスタムコントロールの作成
バインド可能なカスタムコントロールの作成