Unity Graph Editor
今天跟群友聊天聊到Behavior Designer,这是一个Unity行为树的库,突然好奇如何自己在Unity绘制一个Graph Node Editor,简单做了下调研
Handles
Handles的用法和GL很像,你也可以用GL.xxx实现下面的代码
Unity的Handles类本身就可以像OpenGL那样绘制2D Editor
using System; using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; public class DrawGraphWindow : EditorWindow { private static DrawGraphWindow _window; private static float _minZoom = 0.4f; private static float _maxZoom = 7.0f; private static float _zoonSpeed = 0.1f; private Color bgColor = new Color(0.15f, 0.15f, 0.15f); private Color gridColor = new Color(0.85f, 0.85f, 0.85f); private Rect graphRect; private Vector2 drag; private Vector2 offset; private float zoom = 1.0f; private Vector2 dragStart; private float dragSpeed = 0.1f; [MenuItem("Tools/Draw")] public static void PopUp() { _window = GetWindow<DrawGraphWindow>("Draw"); _window.minSize = new Vector2(400, 300); _window.Show(); } private void OnGUI() { SetupSize(); ProcessEvents(Event.current); DrawBackground(); DrawGrid(10 * zoom, 0.2f); DrawGrid(50 * zoom, 0.4f); } private void SetupSize() { graphRect = new Rect(0, 0, position.width, position.height); } private void ProcessEvents(Event e) { if (e.type == EventType.MouseDown && e.button == 1) { dragStart = e.mousePosition; } if (e.type == EventType.MouseDrag && e.button == 1) { drag = e.mousePosition - dragStart; dragStart = e.mousePosition; GUI.changed = true; } if (e.type == EventType.ScrollWheel) { zoom -= _zoonSpeed * e.delta.y; zoom = Mathf.Clamp(zoom, _minZoom, _maxZoom); e.Use(); } } private void DrawBackground() { EditorGUI.DrawRect(graphRect, bgColor); } private void DrawGrid(float gridSpacing, float gridOpacity) { int widthDivs = Mathf.CeilToInt(position.width / gridSpacing); int heightDivs = Mathf.CeilToInt(position.height / gridSpacing); Handles.BeginGUI(); Handles.color = new Color(gridColor.r, gridColor.g, gridColor.b, gridOpacity); offset += drag * dragSpeed; Vector3 newOffset = new Vector3(offset.x % gridSpacing, offset.y % gridSpacing, 0); for (int i = 0; i < widthDivs; i++) { Handles.DrawLine(new Vector3(gridSpacing * i, -gridSpacing, 0) + newOffset, new Vector3(gridSpacing * i, position.height, 0f) + newOffset); } for(int i = 0; i < heightDivs; i++) { Handles.DrawLine(new Vector3(-gridSpacing, gridSpacing * i, 0) + newOffset, new Vector3(position.width, gridSpacing * i, 0) + newOffset); } Handles.color = Color.white; Handles.EndGUI(); } }
|
效果如下,按住鼠标右键可以拖拽,转动滚轮可以缩放
插件
自己重写一份图节点编辑器是非常费劲的,比如要处理反射等信息
你可以尝试使用FlowCanvas、xNode,或者ui toolkit
参考
UnityToolchainsTrick