Unity3D Draggable GUI.Box с элементами управления GUI
Я создаю окно редактора пользовательских узлов в 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.
Любая помощь или предложения, даже толчок к другому источнику будет принята с благодарностью - я чувствую, что использовал все поисковые термины, которые существуют в моей голове!
Редактировать - Решено: Спасибо Клеберу за решение этого вопроса для меня. В случае, если кто-то столкнется с этой или схожей проблемой, я решил, что нужно понять, что элементы управления с графическим интерфейсом автоматически потребляют события левого mousedown, поэтому щелчок по ползунку означает, что нет никакого распространения в Box, чтобы проверить, был ли он нажат.
Мне нужно было разделить флаги IsSelected и IsDragged в классе Node и очистить IsDragged на mouseUp. Изначально я использовал IsSelected, чтобы пометить как перетаскивание, так и выделение (можно было выбрать и перетащить сразу несколько узлов).
1 ответ
Это довольно сложный учебник, поэтому я не прочитал его полностью, но проблема, кажется, заключается в MouseDrag
обнаружение. Ну, в общем, вы хотите остановить распространение событий, когда нажимаете на элемент GUI внутри Box, верно? Для этого звоните:
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()
работать правильно.