我在Unity中构建自定义节点编辑器窗口,我已经查看了this one等各种资源,它使用GUI.Box
来构建节点窗口。< / p>
这很好用,我可以按照我想要的方式拖动这些窗口,但是一旦我将控件添加到GUI.Box
,我希望它们覆盖Drag()
函数I& #39;写了。
以下是问题的一个示例 - 当我向上移动垂直滑块时,整个框都会拖动它。
有没有办法使用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控件自动消耗左侧mousedown事件,因此单击滑块意味着没有传播到Box以检查它是否被点击。
我需要做的是在Node类中分离IsSelected和IsDragged标志,并在mouseUp上清除IsDragged。我最初使用IsSelected标记拖动已启用和已选中(可以一次选择并拖动多个节点)。
答案 0 :(得分:1)
这是一个非常复杂的教程,所以我没有完全阅读它,但问题似乎是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();
}
}
正如您所看到的,此示例并不需要Event.current.Use()
才能正常工作。