1

我正在 Unity 中构建一个自定义节点编辑器窗口,并且我查看了各种资源,例如用于构建GUI.Box节点窗口的资源。

这很好用,我可以按照我想要的方式拖动这些窗口,但是一旦我将控件添加到GUI.Box,我希望它们覆盖Drag()我编写的函数。

这是问题的一个示例 - 当我向上移动垂直滑块时,整个框都会随之拖动。

垂直滑块问题

有没有办法使用 修复这种行为GUI.Box,或者我应该回到GUI.Window它的内置GUI.DragWindow()

这是我正在使用的代码的简化版本:

EditorMouseInput.cs:

private bool ActionLeftMouseDown()
{
    mouseDownNode = editor.GetSelectedNode(Input.current.mousePosition);

    if (mouseDownNode == null)
        editor.StartMovingEditorCanvas();
    else
        mouseDownNode.IsSelected = true;
}

BaseNodeEditor.cs:

public BaseNode GetSelectedNode(Vector2 mousePos)
{
    foreach (BaseNode node in Nodes)
    {
        if (node.WindowRect.Contains(mousePos))
            return node;
    }
    return null;
}

public void Drag(Vector2 delta)
{
    if (!MoveEditorMode && !ConnectionMode)
    {
        foreach (BaseNode node in Nodes)
        {
            node.Drag(delta);
        }
    }

BaseNode.cs:

public void Drag(Vector2 delta)
{
    if (IsSelected)
        draggedDistance += delta;
}

垂直滑块添加到派生的 JumpNode 类中。构造滑块的辅助类的摘录:

Vector2 pos = node.WindowRect.position + rect.position * GridSpacing;
value = GUI.VerticalSlider(new Rect(pos, rect.size * GridSpacing), value, maxValue, minValue);

我明白为什么这不能满足我的要求,但我不知道如何去做,因为 GUI 控件不是 GUI.Box 的一部分。

任何帮助或建议,甚至是对另一个来源的轻推都将不胜感激 - 我觉得我已经使用了我脑海中存在的所有搜索词!

编辑 - 已解决:感谢 Kleber 为我解决了这个问题。万一其他人遇到这个或类似的问题,我的解决方案是意识到 GUI 控件会自动消耗鼠标左键事件,因此单击滑块意味着没有传播到 Box 以检查它是否被单击。

我需要做的是将 Node 类中的 IsSelected 和 IsDragged 标志分开,并在 mouseUp 上清除 IsDragged。我最初使用 IsSelected 来标记启用和选中的拖动(可以一次选择和拖动多个节点)。

4

1 回答 1

2

这是一个相当复杂的教程,所以我没有完整地阅读它,但问题似乎是MouseDrag检测。好吧,基本上你想在单击 Box 内的 GUI 元素时停止事件传播,对吧?为此,您调用:

Event.current.Use()

每次用户在您的一个组件上拖动鼠标时。

使用您提到的资源,我更改了Node类并在Draw()方法中添加了一个滑块,如下所示:

public void Draw() {
    inPoint.Draw();
    outPoint.Draw();
    GUI.Box(rect, title, style);
    GUI.BeginGroup(rect);
    _value = GUI.HorizontalSlider(new Rect(20, 0, 50, 20), _value, 100, -100);
    GUI.EndGroup();
}

第一个例子

您可以做的另一件事是更改绘制窗口的方式。这是我在最新的 Unity 版本(5.6)上测试过的一个简单示例:

private void OnGUI() {
    GUI.Box(_rect, string.Empty);
    GUI.BeginGroup(_rect);

    _value = GUI.VerticalSlider(new Rect(145, 100, 20, 100), _value, 100, -100);
    GUI.EndGroup();

    var e = Event.current;
    if (e.type == EventType.MouseDrag && _rect.Contains(e.mousePosition)) {
        _rect.x += e.delta.x;
        _rect.y += e.delta.y;
        Repaint();
    }
}

如您所见,此示例不需要 aEvent.current.Use()即可正常工作。

第二个例子

于 2017-05-13T18:37:42.157 回答