Version: Unity 6.0 (6000.0)
语言 : 中文
使用自定义控件响应事件
合成和发送事件

操控器

要将事件逻辑与__ UI__(即用户界面,User Interface)让用户能够与您的应用程序进行交互。Unity 目前支持三种 UI 系统。更多信息
See in Glossary
代码分开,请使用操控器来处理事件。操控器是处理用户与 UI 元素交互的状态机。它们存储、注册和取消注册事件回调。操控器可以简化用户交互的设置,因此不必逐个处理每个回调。要处理事件,请使用或继承 UI 工具包支持的一种操控器。

要创建和使用操控器,请执行以下操作:

  1. 定义一个继承自 UI 工具包支持的操控器类的专用类。此类封装了针对要管理的特定用户交互而定制的事件处理逻辑。
  2. 在类中,实现方法来响应相关交互,例如鼠标单击或拖动。这些方法可以捕获和处理必要的信息以执行所需的行为。
  3. 完成操控器类的设计后,请实例化该类并将其附加到目标 UI 元素。此附件允许操控器拦截和管理指定事件,从而协调用户交互,同时与 UI 代码保持清晰分离。

支持的操控器

下表列出了支持的操控器类:

操控器 继承自 描述
Manipulator 所有提供的操控器的基类。
KeyboardNavigationManipulator Manipulator 使用键盘处理特定于设备的输入事件到更高级导航操作的转换。
MouseManipulator Manipulator 处理鼠标输入。具有激活过滤器列表。
ContextualMenuManipulator MouseManipulator 当用户单击鼠标右键或按下键盘上的菜单键时显示上下文菜单。
PointerManipulator MouseManipulator 处理指针输入。具有激活过滤器列表。
Clickable PointerManipulator 跟踪元素上的鼠标事件,并识别发生点击的时间,即在同一元素上按下和释放指针的时间。

示例

以下示例演示了如何使用操控器处理事件。执行的操作如下:

创建 ExampleDragger 操控器

以下示例将创建操控器,可在单击并拖动元素时移动元素:

using UnityEngine;
using UnityEngine.UIElements;

public class ExampleDragger : PointerManipulator
{
    private Vector3 m_Start;
    protected bool m_Active;
    private int m_PointerId;
    private Vector2 m_StartSize;

    public ExampleDragger()
    {
        m_PointerId = -1;
        activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse });
        m_Active = false;
    }

    protected override void RegisterCallbacksOnTarget()
    {
        target.RegisterCallback<PointerDownEvent>(OnPointerDown);
        target.RegisterCallback<PointerMoveEvent>(OnPointerMove);
        target.RegisterCallback<PointerUpEvent>(OnPointerUp);
    }

    protected override void UnregisterCallbacksFromTarget()
    {
        target.UnregisterCallback<PointerDownEvent>(OnPointerDown);
        target.UnregisterCallback<PointerMoveEvent>(OnPointerMove);
        target.UnregisterCallback<PointerUpEvent>(OnPointerUp);
    }

    protected void OnPointerDown(PointerDownEvent e)
    {
        if (m_Active)
        {
            e.StopImmediatePropagation();
            return;
        }

        if (CanStartManipulation(e))
        {
            m_Start = e.localPosition;
            m_PointerId = e.pointerId;

            m_Active = true;
            target.CapturePointer(m_PointerId);
            e.StopPropagation();
        }
    }

    protected void OnPointerMove(PointerMoveEvent e)
    {
        if (!m_Active || !target.HasPointerCapture(m_PointerId))
            return;

        Vector2 diff = e.localPosition - m_Start;

        target.style.top = target.layout.y + diff.y;
        target.style.left = target.layout.x + diff.x;

        e.StopPropagation();
    }

    protected void OnPointerUp(PointerUpEvent e)
    {
        if (!m_Active || !target.HasPointerCapture(m_PointerId) || !CanStopManipulation(e))
            return;

        m_Active = false;
        target.ReleaseMouse();
        e.StopPropagation();
    }
}

创建 ExampleResizer 操控器

以下示例将创建操控器,可在拖动元素时调整元素的大小:

using UnityEngine;
using UnityEngine.UIElements;

public class ExampleResizer : PointerManipulator
{
    private Vector3 m_Start;
    protected bool m_Active;
    private int m_PointerId;
    private Vector2 m_StartSize;
    public ExampleResizer()
    {
        m_PointerId = -1;
        activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse });
        m_Active = false;
    }

    protected override void RegisterCallbacksOnTarget()
    {
        target.RegisterCallback<PointerDownEvent>(OnPointerDown);
        target.RegisterCallback<PointerMoveEvent>(OnPointerMove);
        target.RegisterCallback<PointerUpEvent>(OnPointerUp);
    }

    protected override void UnregisterCallbacksFromTarget()
    {
        target.UnregisterCallback<PointerDownEvent>(OnPointerDown);
        target.UnregisterCallback<PointerMoveEvent>(OnPointerMove);
        target.UnregisterCallback<PointerUpEvent>(OnPointerUp);
    }

    protected void OnPointerDown(PointerDownEvent e)
    {
        if (m_Active)
        {
            e.StopImmediatePropagation();
            return;
        }

        if (CanStartManipulation(e))
        {
            m_Start = e.localPosition;
            m_StartSize = target.layout.size;
            m_PointerId = e.pointerId;
            m_Active = true;
            target.CapturePointer(m_PointerId);
            e.StopPropagation();
        }
    }

    protected void OnPointerMove(PointerMoveEvent e)
    {
        if (!m_Active || !target.HasPointerCapture(m_PointerId))
            return;

        Vector2 diff = e.localPosition - m_Start;

        target.style.height = m_StartSize.y + diff.y;
        target.style.width = m_StartSize.x + diff.x;

        e.StopPropagation();
    }

    protected void OnPointerUp(PointerUpEvent e)
    {
        if (!m_Active || !target.HasPointerCapture(m_PointerId) || !CanStopManipulation(e))
            return;

        m_Active = false;
        target.ReleasePointer(m_PointerId);
        m_PointerId = -1;
        e.StopPropagation();
    }
}

添加或删除操控器

要将操控器添加到元素,请使用 AddManipulator 方法。要从元素中删除操控器,请使用 RemoveManipulator 方法。

以下示例将向 VisualElement 添加和删除 ExampleDragger

// Create a VisualElement.
var myElement = new VisualElement();

// Add manipulators to the VisualElement.
myElement.AddManipulator(new ExampleDragger());

// Remove manipulators from the VisualElement.
myElement.RemoveManipulator<ExampleDragger>();

以下示例将 ExampleResizer 添加到 VisualElement

var box = new VisualElement()
{
    style =
    {
        left = 100,
        top = 100,
        width = 100,
        height = 100,
        backgroundColor = Color.red
    },
    pickingMode = PickingMode.Position,
};

box.AddManipulator(new ExampleResizer());

其他资源

使用自定义控件响应事件
合成和发送事件