User interface 带有GUI控件的Unity3D可拖动GUI.Box

User interface 带有GUI控件的Unity3D可拖动GUI.Box,user-interface,unity3d,unity-editor,User Interface,Unity3d,Unity Editor,我正在Unity中构建一个自定义节点编辑器窗口,我已经查看了各种资源,例如,它使用GUI.Box构建节点窗口 这非常有效,我可以按照我想要的方式拖动这些窗口,但是一旦我将控件添加到GUI.Box,我希望它们覆盖我编写的drag()函数 这里有一个问题的例子——当我向上移动垂直滑块时,整个框都会随之拖动 有没有办法使用GUI.Box修复此行为,或者我是否应该使用内置的GUI.DragWindow()返回到GUI.Window 下面是我正在使用的代码的简化版本: EditorMouseInput.

我正在Unity中构建一个自定义节点编辑器窗口,我已经查看了各种资源,例如,它使用
GUI.Box
构建节点窗口

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

这里有一个问题的例子——当我向上移动垂直滑块时,整个框都会随之拖动

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

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

EditorMouseInput.cs:

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

    if (mouseDownNode == null)
        editor.StartMovingEditorCanvas();
    else
        mouseDownNode.IsSelected = true;
}
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);
        }
    }
public void Drag(Vector2 delta)
{
    if (IsSelected)
        draggedDistance += delta;
}
BaseNodeEditor.cs:

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

    if (mouseDownNode == null)
        editor.StartMovingEditorCanvas();
    else
        mouseDownNode.IsSelected = true;
}
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);
        }
    }
public void Drag(Vector2 delta)
{
    if (IsSelected)
        draggedDistance += delta;
}
BaseNode.cs:

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

    if (mouseDownNode == null)
        editor.StartMovingEditorCanvas();
    else
        mouseDownNode.IsSelected = true;
}
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);
        }
    }
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控件会自动使用鼠标左键向下事件,因此单击滑块意味着不会传播到复选框以检查是否单击它


我需要做的是在Node类中分离IsSelected和isDraged标志,并在mouseUp上清除isDraged。我最初使用IsSelected来标记“已启用拖动”和“已选择”(可以同时选择和拖动多个节点)。

这是一个相当复杂的教程,因此我没有完全阅读它,但问题似乎在于
鼠标拖动检测。基本上,当您单击框中的GUI元素时,您希望停止事件传播,对吗?为此,您可以拨打:

Event.current.Use()
每次用户在组件上拖动鼠标时

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

public void Draw(){
inPoint.Draw();
outPoint.Draw();
GUI.Box(矩形、标题、样式);
GUI.BeginGroup(rect);
_value=GUI.HorizontalSlider(新的Rect(20,0,50,20),_值,100,-100);
GUI.EndGroup();
}

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

private void OnGUI(){
Box(_rect,string.Empty);
GUI.BeginGroup(_rect);
_value=GUI.verticalslaider(新的Rect(145100,20100),_值,100,-100);
GUI.EndGroup();
var e=事件电流;
if(e.type==EventType.MouseDrag&&rect.Contains(e.mousePosition)){
_矩形x+=e.delta.x;
_矩形y+=e.delta.y;
重新油漆();
}
}
如您所见,此示例不需要
Event.current.Use()
来正常工作


感谢您的回复!Event.current.Use()肯定可以工作,尽管我的问题在于滑块控件(或任何控件)不存在于框中,它只是在框的顶部绘制。我还使用内置的GUI控件,因此在单击、选择、拖动等
事件时,我看不到事件。当前的
仅在
OnGUI()
中可访问,因此它仅适用于IMGUI系统。例如,您发送的资源使用了
Event.current
作为
ProcessEvents()
方法的参数发送。我编辑了我的答案,添加了其他可行的解决方案。首先,我非常感谢您在这一点上花时间。我发现了问题所在——这需要一点思维上的转变,而你确实帮助我实现了这一目标。我有一个MouseEventHandler脚本,它没有清除mouseup上的选择(以允许选择多个框)。我没有意识到控件会自动消耗事件,所以我找错了地方。拖动框意味着当我拖动滑块时它保持选中状态。