ue3dUnity中的UIToolkit鼠标捕获机制

Unity中的UIToolkit鼠标捕获机制

分类:
ue3d - Unity中的UIToolkit鼠标捕获机制

本文将介绍Unity中的UI Toolkit(UI工具)中的鼠标捕获机制,首先需要了解什么是鼠标捕获。

什么是鼠标捕获?

现在考虑在UI元素上单击鼠标、拖动和释放,可以通过为以下事件注册回调来接收此类鼠标事件:

  • 鼠标按下:MouseDownEvent
  • 鼠标移动:MouseMoveEvent
  • 鼠标释放:MouseUpEvent

要测试这些行为,请创建一个UI排列如下的EditorWindow。

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public sealed class CaptureExample : EditorWindow
{
    private bool _isCapturing;

    public void CreateGUI()
    {
        // layout
        // Place child in the center of root
        var root = rootVisualElement;
        root.style.paddingTop = 100;
        root.style.paddingBottom = 100;
        root.style.paddingLeft = 100;
        root.style.paddingRight = 100;
        root.style.backgroundColor = new StyleColor(new Color(0.8f, 0.8f, 0.8f));

        var child = new VisualElement
        {
            style =
            {
                height = new StyleLength(Length.Percent(100)),
                borderBottomLeftRadius = 12,
                borderBottomRightRadius = 12,
                borderTopLeftRadius = 12,
                borderTopRightRadius = 12,
                backgroundColor = new StyleColor(new Color(0.3f, 0.3f, 0.3f))
            }
        };

        root.Add(child);

        // Register an event for child
        child.RegisterCallback<MouseUpEvent>(_ => Debug.Log("MouseUpEvent"));
        child.RegisterCallback<MouseDownEvent>(_ => Debug.Log("MouseDownEvent"));
        child.RegisterCallback<MouseMoveEvent>(_ => Debug.Log("MouseMoveEvent"));
    }

    [MenuItem("Window/CaptureExample")]
    public static void ShowWindow()
    {
        GetWindow<CaptureExample>("CaptureExample");
    }
}

当运行它时,会看到一个像这样的窗口:

如果将鼠标拖动到中间的圆角矩形内,可以看到上面注册的每个事件都被触发了。

ue3d - Unity中的UIToolkit鼠标捕获机制

接下来,在这个child的内部按下鼠标,并在按住鼠标的同时将鼠标移动到child的外部。然后可以看到在圆角矩形之外不会调用。

这样,只有当鼠标悬停在注册回调的UI元素上时,才会调用鼠标事件MouseMoveEventMouseUpEvent。

如果在这里让子UI元素捕获鼠标,鼠标事件就会发给这个UI元素,直到释放捕获。这意味着将在捕获鼠标时在child外部调用MouseMoveEvent,MouseUpEvent要么显式释放鼠标捕获,要么在单击另一个元素时释放捕获。

检查鼠标捕获行为

那么,实际检查鼠标捕获的行为,以下脚本是将捕获过程添加到上面的EditorWindow的脚本。

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public sealed class CaptureExample : EditorWindow
{
    private bool _isCapturing;

    public void CreateGUI()
    {
        // layout
        // Place child in the center of root
        var root = rootVisualElement;
        root.style.paddingTop = 100;
        root.style.paddingBottom = 100;
        root.style.paddingLeft = 100;
        root.style.paddingRight = 100;
        root.style.backgroundColor = new StyleColor(new Color(0.8f, 0.8f, 0.8f));

        var child = new VisualElement
        {
            style =
            {
                height = new StyleLength(Length.Percent(100)),
                borderBottomLeftRadius = 12,
                borderBottomRightRadius = 12,
                borderTopLeftRadius = 12,
                borderTopRightRadius = 12
            }
        };

        root.Add(child);

        // Register events for child
        // If child is capturing the mouse, these events will also react elsewhere
        child.RegisterCallback<MouseUpEvent>(_ => Debug.Log("MouseUpEvent"));
        child.RegisterCallback<MouseDownEvent>(_ => Debug.Log("MouseDownEvent"));
        child.RegisterCallback<MouseMoveEvent>(_ => Debug.Log("MouseMoveEvent"));

        // Change the color according to the mouse capture state
        void SetChildColor()
        {
            child.style.backgroundColor = _isCapturing
                ? new StyleColor(new Color(0.3f, 0.8f, 0.3f))
                : new StyleColor(new Color(0.3f, 0.3f, 0.3f));
        }

        child.RegisterCallback<MouseDownEvent>(evt =>
        {
            // Capture/release mouse when clicked
            if (_isCapturing)
            {
                child.ReleaseMouse();
                _isCapturing = false;
            }
            else
            {
                child.CaptureMouse();
                // It's possible.
                //MouseCaptureController.ReleaseMouse();
                _isCapturing = true;
            }

            SetChildColor();
        });
        SetChildColor();
    }

    [MenuItem("Window/CaptureExample")]
    public static void ShowWindow()
    {
        GetWindow<CaptureExample>("CaptureExample");
    }
}

当显示此窗口并单击子项时,鼠标被捕获并且子项变为绿色,如果鼠标被捕获并且将鼠标移到子项之外,可以看到正在调用的鼠标事件。

通过再次单击子元素或单击另一个UI元素来释放鼠标捕获。

ue3d - Unity中的UIToolkit鼠标捕获机制

捕获事件

当元素捕获和取消捕获鼠标时,还可以将事件注册为回调。

为此,请按以下MouseCaptureEvent方式MouseCaptureOutEvent使用或:

child.RegisterCallback<MouseCaptureEvent>(_ => Debug.Log( "MouseCaptureEvent" )); 
child.RegisterCallback<MouseCaptureOutEvent>(_ => Debug.Log( "MouseCaptureOutEvent" ));

以上是Unity的UIToolkit鼠标捕获机制介绍的全部内容,如果你有任何反馈,请随时在本页面下方留言。

相关信息

  • 类型:知识
  • 字数:594
  • 字符:5600
  • 适用软件:Unity
  • 说明:无
  • 编号:159732

热门内容

提示:3D天堂作为服务提供者,尊重网络版权及知识产权,对某些行为的发生不具备充分的监控能力,若无意间侵犯到您的权利,请 联系我们,我们会在收到信息后尽快给予处理。

本站文章版权归本站自创作者所有,未经允许不得转载!