[toc]
# 蓝图开发
# 1. 实现蓝图组
主要功能点有几个:
- 更改功能组的标题
- 拖拽右下角可以对功能组的大小进行调整
- 可以吸附功能组内的元素一起移动
- 保证在所有元素最下方
# 1. 更改功能组标题
这个比较简单,直接暴露一个标题参数,然后在 Editor 的 OnHeaderGUI
重载中刷新题头
1 2 3 4 5
| public override void OnHeaderGUI() { var self = group; GUILayout.Label(self.title, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30)); }
|
# 2. 拖拽右下角对功能组大小进行调整
- 首先在鼠标触发 MouseDown 事件时判断是否在包围盒的右下角
这里可以使用 OnGui 中的 Event
进行鼠标事件的捕获 https://blog.csdn.net/qq_36383623/article/details/100184153 在 XNode 中的 OnXXXGUI
实际上都是从 OnGUI 中延伸出来的:
1
| NodeEditorWindow.OnGUI -> DrawNodes() -> graph.nodes.OnHeaderGUI()/OnBodyGUI()
|
这样,所以在 OnBodyGUI 中实际上也可以直接使用 OnGUI 中的 Event
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public override void OnBodyGUI() { Event e = Event.current; switch (e.type) { case EventType.MouseDrag: break; case EventType.MouseDown: if (e.button != 0) return; if(NodeEditorWindow.current.nodeSizes.TryGetValue(target,out size)) { Rect lowerRight = new Rect(size.x - 34, size.y - 34, 30, 30); if (lowerRight.Contains(e.mousePosition)) { isDragging = true; } } break; case EventType.MouseUp: break; case EventType.Repaint: break;
} }
|
如上述代码,直接在 Node 的 Boundary 中进行判断当前鼠标是否在右下角即可
如果鼠标在右下角进行的点击,则进入拖拽态
- 拖拽时对 Node 的 Gui 进行重绘,更新 Node 的长和宽,同时重新绘制 Node
其中有一个小 trick, 就是显示拖拽指针的效果
1 2 3 4 5 6 7 8 9 10 11 12 13
| if (NodeEditorWindow.current.nodeSizes.TryGetValue(target, out size)) { Rect lowerRight = new Rect(target.position, new Vector2(30, 30)); lowerRight.y += size.y - 34; lowerRight.x += size.x - 34; lowerRight = NodeEditorWindow.current.GridToWindowRect(lowerRight); NodeEditorWindow.current.onLateGUI += () => AddMouseRect(lowerRight); }
public static void AddMouseRect(Rect rect) { EditorGUIUtility.AddCursorRect(rect, MouseCursor.ResizeUpLeft); }
|
其实只需要当鼠标在可拖拽的范围内时更改鼠标的滚轮样式即可 Editor 下更改鼠标滚轮的样式可以使用: EditorGUIUtility.AddCursorRect(rect, MouseCursor.ResizeUpLeft);
# 3. 吸附包围盒内的元素一起移动
- 直接判断有哪些元素在包围盒内 (包里 for nodes, 以及判断 每个 node 是否在当前 NodeGroup 的范围内)
- 加到 Selection Node 中即可
1
| Selection.objects = selection.Distinct().ToArray();
|
# 4. 保证在所有元素最下方
1 2 3 4 5 6
| if (target.graph.nodes.IndexOf(target) != 0) { target.graph.nodes.Remove(target); target.graph.nodes.Insert(0, target); }
|
每次 Repaint 判断是否在最下方,不是就移到最下方
# 附:大佬画的 XNode 架构图