如何为图形或树结构编写 GUI 编辑器
Posted
技术标签:
【中文标题】如何为图形或树结构编写 GUI 编辑器【英文标题】:How to write a GUI editor for Graph or Tree structures 【发布时间】:2013-07-11 12:14:13 【问题描述】:Unity3D
的 Mecanim
动画系统有一个自定义的 EditorWindow
,它允许通过 GUI 定义一棵树(在本例中为混合树)。
看起来像:
它提供了创建节点(状态)和连接它们(转换)的可能性。
现在,我正在开发一些图形和树结构,我想编写一个编辑器扩展,以便让我的游戏设计师填充这些结构。
我最想重新创建一个 EditorWindow
,就像 Mecanim 动画师(上图)一样。
我的问题是:是否有任何可用的组件可用于此类任务?是否有用于绘图和连接框和箭头的内置类?或者我需要自己编写完整的 GUI 元素?
【问题讨论】:
我不知道这是否对您有很大帮助,但举个例子,here is a nice post 我曾经在我的编辑器窗口中做贝塞尔线。这是一个很好的例子。 @Jerdak:谢谢.. 非常有趣。我去看看。 @Jerdak 也感谢您的链接!出于兴趣,我正在看这个,因为我想要一些与我的状态机的 MechanimEditor 非常相似的东西。 我看到的只有线条、箭头和文本框。所以你有它们的集合,你需要写一些可以创建和存储这样一个集合的东西 @Jerdak:我找到了一种在编辑器中绘制贝塞尔线的更简单方法。如果您将 Handles.DrawBezier 与 Handles.BeginGUI/EndGUI 放在一起,您可以使用统一函数在编辑器窗口中绘图。我很快就会发布一个sn-p。 【参考方案1】:我不是在问“寻找工具、库或最喜欢的场外资源”。我想知道如何使用Unity3D
API 或引擎本身提供的一些可用组件重现Mecanim
之类的图形编辑器(对不起,如果问题不清楚)。
这是我的答案:
不,没有可用的组件可用于绘制这种图形,但编写自己的非常容易。这是一个带有简单示例的 sn-p,使用可拖动的 GUI.Window 表示节点,Handles.DrawBezier 绘制边缘:
public class GraphEditorWindow : EditorWindow
Rect windowRect = new Rect (100 + 100, 100, 100, 100);
Rect windowRect2 = new Rect (100, 100, 100, 100);
[MenuItem ("Window/Graph Editor Window")]
static void Init ()
EditorWindow.GetWindow (typeof (GraphEditorWindow));
private void OnGUI()
Handles.BeginGUI();
Handles.DrawBezier(windowRect.center, windowRect2.center, new Vector2(windowRect.xMax + 50f,windowRect.center.y), new Vector2(windowRect2.xMin - 50f,windowRect2.center.y),Color.red,null,5f);
Handles.EndGUI();
BeginWindows();
windowRect = GUI.Window (0, windowRect, WindowFunction, "Box1");
windowRect2 = GUI.Window (1, windowRect2, WindowFunction, "Box2");
EndWindows();
void WindowFunction (int windowID)
GUI.DragWindow();
【讨论】:
感谢您的回答。你得到你想要的了吗?我也在尝试制作一些简单的状态机图,因此如果您可以分享它们,我对您的发现很感兴趣:) @vexe:不,我没有完成实现它。我正在从事几个不同的项目,不幸的是,这具有最低的优先级。如果您想合作实施它,请告诉我,我们最终可以一起做一些事情。 壮观!令人惊讶的是有多少教程只是纯粹的废话。我已经挖掘了几个小时,阅读了 200 多行长的帖子,这个简单的 30 行代码解决了我的问题。谢谢!【参考方案2】:你错了,伙计。您在 UnityEditor 中看到的所有内容都必须在某处有代码。您的 MecanimEditor 位于命名空间 UnityEditor.Graphs.AnimationStateMachine。
扩展 UnityEditor.Graphs 中的 GraphGUI。该类负责绘制图形。
using System;
using UnityEditor;
using UnityEngine;
using UnityEditor.Graphs;
using System.Collections.Generic;
namespace ws.winx.editor.components
public class GraphGUIEx:GraphGUI
创建新的编辑器窗口。
public class GraphEditorWindow : EditorWindow
static GraphEditorWindow graphEditorWindow;
Graph stateMachineGraph;
GraphGUIEx stateMachineGraphGUI;
[MenuItem("Window/Example")]
static void Do ()
graphEditorWindow = GetWindow<grapheditorwindow> ();
....
创建图形结构。它将包含节点和节点之间的边。
stateMachineGraph = ScriptableObject.CreateInstance<Graph> ();
stateMachineGraph.hideFlags = HideFlags.HideAndDontSave;
//create new node
Node node=ScriptableObject.CreateInstance<Node>();
node.title="mile2";
node.position=new Rect(400,34,300,200);
node.AddInputSlot("input");
start=node.AddOutputSlot("output");
node.AddProperty(new Property(typeof(System.Int32),"integer"));
stateMachineGraph.AddNode(node);
//create new node
Node node=ScriptableObject.CreateInstance<Node>();
node.title="mile";
node.position=new Rect(0,0,300,200);
Slot end=node.AddInputSlot("input");
node.AddOutputSlot("output");
node.AddProperty(new Property(typeof(System.Int32),"integer"));
stateMachineGraph.AddNode(node);
//create edge
stateMachineGraph.Connect(start,end);
graphGUI = ScriptableObject.CreateInstance<GraphGUIEx>();
graphGUI.graph = graph;
画图。
void OnGUI ()
if (graphEditorWindow && stateMachineGraphGUI != null)
stateMachineGraphGUI.BeginGraphGUI (graphEditorWindow, new Rect (0, 0, graphEditorWindow.position.width, graphEditorWindow.position.height));
stateMachineGraphGUI.OnGraphGUI ();
stateMachineGraphGUI.EndGraphGUI ();
覆盖 NodeGUI 或 EdgeGUI 以获得更多样式和绘图控制。 从 UnityEditor.Graphs.AnimationStateMachine.GraphGUI 样式复制粘贴代码,在 NodeGUI 和 EdgeGUI 中完成。
【讨论】:
我会检查的。在提出这个问题时,Graphs api 并未公开。感谢您的信息。 令人印象深刻。谢谢! UnityEditor.Graphs.AnimationStateMachine 命名空间似乎不存在(unity 5.4)【参考方案3】:这个话题相当复杂,但是如果你想要一个不错的启动脚本存储库,请查看 Unity 官方网站上的这个论坛帖子http://forum.unity3d.com/threads/simple-node-editor.189230/
*更新:有人发布了一个复杂的教程系列,详细说明了如何准确地创建您所描述的内容。享受https://www.youtube.com/watch?v=gHTJmGGH92w。
编辑:我在 GitHub 存储库中编写了一个功能齐全的 Unity 图形编辑器。主要集中在技能树上。它并不完美,但展示了功能齐全的图形编辑器的外观。源代码在以下链接中。
https://github.com/ashblue/unity-skill-tree-editor
【讨论】:
【参考方案4】:您可以尝试为每个树对象内部的数据创建一个对象。 然后您可以尝试使用 System.Drawing 创建自定义控件(图片中的方框),也可以使用 System.Drawing 为每个树对象创建这些箭头。确保每个 DataObject 都有 ID 和箭头应该指向的位置的信息。 如果您在创建自定义控件方面需要帮助,我过去曾在 YouTube 上使用过 this 教程。
【讨论】:
【参考方案5】:我从Unity AssetStore找到了一个Unity UI FlowChart Asset,UI Graph,由Broken Machinery开发,免费使用!
【讨论】:
【参考方案6】:我已经完成了一个使用 TreeViewer 和复选框创建自定义图形的界面。是基于“邻接表”的想法。如果您选中了“根”顶点的复选框,它会使其与另一个顶点相邻,如果您只想让几个顶点相邻,那么您可以单独选择每个顶点。我已经为 java 开发了这个,但我相信它也可以用于你的目的。这是一张我希望能阐明我的想法的图片。
http://i.stack.imgur.com/3PhT9.jpg
【讨论】:
以上是关于如何为图形或树结构编写 GUI 编辑器的主要内容,如果未能解决你的问题,请参考以下文章
如何为python类中的私有属性编写getter-setter方法?