版本:Unity 6 (6000.0)
语言:英语
创建具有两个属性的自定义控件
创建可绑定的自定义控件

创建滑动切换自定义控件

版本: 2023.2+

此示例演示如何创建切换的“类似开关”变体。

示例概述

此示例创建了一个自定义控件:一个用户可以使用鼠标、键盘、游戏手柄和其他设备来翻转的切换。它带有一个可以描述切换代表内容的标签。

您可以在此 GitHub 仓库 中找到此示例创建的完整文件。

先决条件

本指南适用于熟悉 Unity 编辑器、UI(用户界面) 允许用户与您的应用程序交互。Unity 目前支持三种 UI 系统。 更多信息
请参阅 术语表
工具包和 C# 脚本的开发人员。在开始之前,请熟悉以下内容

创建滑动切换类

使用 C# 脚本创建滑动切换类。

  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.
    [UxmlElement]
    public partial class SlideToggle : BaseField<bool>
    {
        // 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);

            // 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);
        }
    }
}

为滑动切换设置样式

使用 USS 文件为滑动切换设置样式。

  1. slide-toggle 文件夹中,创建一个名为 SlideToggle.uss 的 USS 文件。
  2. 在文本编辑器中打开 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 生成器将滑动切换添加到 UXML 文件中

  1. slide-toggle 文件夹中,创建一个名为 SlideToggleUsage.uxml 的 UI 文档文件。
  2. 在 UI 生成器中打开 SlideToggleUsage.uxml
  3. 在 UI 生成器中,选择 **库** > **项目** > **MyUILibrary**。
  4. 将一个 **SlideToggle** 拖动到 **层次结构** 窗口中。
  5. 在 **检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑这些值。 更多信息
    请参阅 术语表
    ** 中,在 **标签** 字段中输入切换的标签文本。
  6. 在 **样式表** 部分中,添加 SlideToggle.uss 作为现有的 USS。
  7. 保存并关闭 UI 生成器。

测试滑动切换

  1. 在 SampleScene 中,创建一个 UI 文档 游戏对象Unity 场景中的基本对象,可以代表角色、道具、场景、相机、路径点等等。游戏对象的函数由附加到它的组件定义。 更多信息
    请参阅 术语表
  2. 选择 UI 文档,并将 SlideToggleUsage.uxml 拖动到 **检查器** 中的 **源资产** 字段。
  3. 进入播放模式。您可以点击切换、按 Enter、按 Return 或按空格键来使其来回翻转。

其他资源

创建具有两个属性的自定义控件
创建可绑定的自定义控件