Version: 6000.3
语言: 中文
使用自定义控件响应事件
合成和发送事件

机器人

要将事件逻辑与界面代码分开,请使用纵器来处理事件。机械手是状态机Animator 控制器中角色或动画游戏对象可以处于的状态集,以及这些状态之间的一组转换和用于记住当前状态的变量。可用的状态取决于游戏的类型,但典型的状态包括空闲、行走、奔跑和跳跃等。更多信息
请参阅术语表
处理用户与 UI 元素的交互。它们存储、注册和注销事件回调。纵器简化了用户交互的设置,因此您不必逐个处理每个回调。若要处理事件,请使用 UI 工具包支持的纵器之一或继承其中一个作器。

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

  1. 定义一个专用类,该类继承自 UI Toolkit 支持的纵器类。此类封装了针对要管理的特定用户交互量身定制的事件处理逻辑。
  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方法。

以下示例添加和删除ExampleDragger设置为VisualElement:

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

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

// Remove manipulators from the VisualElement.
myElement.RemoveManipulator(dragger);

以下示例将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());

其他资源

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