Version: 2022.2
言語: 日本語
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. SlideToggle を Hierarchy ウィンドウにドラッグします。
  5. Inspector で、Label にトグルのラベルテキストを入力します。
  6. StyleSheets セクションに、既存の USS として SlideToggle.uss を加えます。
  7. UI Builder を保存して終了します。

スライドトグルのテスト

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

その他の参考資料

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