Unity3D :创建滑动切换自定义控件

推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生

创建滑动切换自定义控件

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

示例概述

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

您可以在此 GitHub 存储库中找到此示例创建的已完成文件。

先决条件

本指南适用于熟悉 Unity 编辑器的开发人员,用户界面
工具包和 C# 脚本。在开始之前,请熟悉以下内容:

  • 用户界面生成器
  • 可视化树
  • 用户体验
  • 美国航空母舰
  • 处理事件

创建幻灯片切换开关并设置其样式

使用 C# 脚本创建幻灯片切换类,并使用 USS 文件设置其样式。

  1. 使用 3D 模板创建 Unity 项目。对于此示例,3D 模板具有更好的视觉效果。但是,您可以使用任何模板。
  2. 创建一个名为用于存储文件的文件夹。slide-toggle
  3. 在该文件夹中,创建一个名为 的 C# 脚本。slide-toggleSlideToggle.cs
  4. 在文本编辑器中打开并用以下内容替换其内容:SlideToggle.cs

using UnityEngine;
using UnityEngine.UIElements;

namespace MyUILibrary
{
// Derives from BaseField base class. Represents a container for its input part.
public class SlideToggle : BaseField
{
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. 在该文件夹中,创建一个名为 的 USS 文件。slide-toggleSlideToggle.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 生成器将幻灯片切换添加到 UXML 文件

  1. 在该文件夹中,创建一个名为 的 UI 文档文件。slide-toggleSlideToggleUsage.uxml
  2. 在 UI 生成器中打开。SlideToggleUsage.uxml
  3. 在 UI 生成器中,选择“>项目”>“MyUILibrary”。
  4. 拖动幻灯片切换到层次结构窗口
  5. 检查员
    ,在标签字段中输入切换的标签文本。
  6. 样式表中,添加为现有 USS。SlideToggle.uss
  7. 保存并关闭 UI 生成器。

测试幻灯片切换

  1. 在示例场景中,创建一个 UI 文档游戏对象
    .
  2. 选择 UI 文档,然后拖到检查器的“源资源”字段中。SlideToggleUsage.uxml
  3. 进入播放模式。您可以单击切换开关,按 Enter 键,按回车键,或按空格键并使其来回翻转。

3D建模学习工作室整理翻译,转载请注明出处!

上一篇:Unity3D :创建具有两个属性的自定义控件 (mvrlink.com)

下一篇:Unity3D :使用网格 API 创建径向进度指示器 (mvrlink.com)

NSDT场景编辑器 | NSDT 数字孪生 | GLTF在线编辑器 | 3D模型在线转换 | UnrealSynth虚幻合成数据生成器 | 3D模型自动纹理化工具
2023 power by nsdt©鄂ICP备2023000829号