C# 如何为图形或树结构编写 GUI 编辑器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17593101/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write a GUI editor for Graph or Tree structures
提问by Heisenbug
Unity3D's Mecanimanimations system has a custom EditorWindowthat allows to define a tree (a blend tree in this case) thorough GUI.
Unity3D的Mecanim动画系统有一个自定义EditorWindow,允许定义一个树(在这种情况下是一个混合树)完整的 GUI。
It looks like:
看起来像:


It offers the possibility of creating nodes (states) and connect them (transitions).
它提供了创建节点(状态)并连接它们(转换)的可能性。
Now, I'm developing some graph and and tree structure and I would like to write an editor extension in order to allow my game designer to populate those structures.
现在,我正在开发一些图形和树结构,我想编写一个编辑器扩展,以便我的游戏设计师能够填充这些结构。
I want pretty most recreate exactly an EditorWindowlike the one of Mecanim animator (figure above).
我最想重新创建一个完全EditorWindow像 Mecanim 动画师(上图)的人。
My question is: are there any available components that I can use for such a task? Is there any builtin class used for the drawing and connecting boxes and arrow? Or I need to write completely the GUI elements by my own?
我的问题是:是否有任何可用的组件可以用于此类任务?是否有用于绘图和连接框和箭头的内置类?或者我需要完全自己编写 GUI 元素?
采纳答案by Heisenbug
I was not asking "for a find a tool, library or favorite off-site resource". I would like to know how reproduce a Mecanimlike graph editor using Unity3DAPI or some available components provided by the engine itself (sorry if the question wasn't clear).
我不是在要求“寻找工具、图书馆或最喜欢的场外资源”。我想知道如何Mecanim使用Unity3DAPI 或引擎本身提供的一些可用组件来重现类似的图形编辑器(对不起,如果问题不清楚)。
Here's my answer:
这是我的回答:
No, there's isn't an available component usable as is to draw that kind of graph, but it's quite easy to write your own. Here's a snippet with a simple example using draggable GUI.Windowto represent nodes and Handles.DrawBezierto draw the edges:
不,没有可用的组件来绘制这种图形,但是编写自己的图形很容易。这是一个带有简单示例的片段,使用可拖动的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();
}
}
回答by McSwaggens
You could try making an Object for the data inside of each tree objects. Then you could try using System.Drawing to create a custom control(square boxes in the picture), also use System.Drawing to create those arrows to each tree object. make sure each DataObject has ID's and information for where the arrows should be pointing. If you need help on creating custom controls i have used thistutorial on YouTube in the past.
您可以尝试为每个树对象内部的数据创建一个对象。然后您可以尝试使用 System.Drawing 创建自定义控件(图片中的方框),也可以使用 System.Drawing 创建指向每个树对象的箭头。确保每个数据对象都有 ID 和箭头应该指向的位置的信息。如果您在创建自定义控件方面需要帮助,我过去曾在 YouTube 上使用过本教程。
回答by robertwolfheart
I've done an interface for creating custom graphs using a TreeViewer and checkboxers. Is based on an "adjacency list" idea. If you have the checkbox of the "root" vertex checked, it makes it adjacent to the other vertex, if you just want a few vertex to be adjacent, then you select each one separetaly. I've developed this for java, but I believe it could also work for your purpose. Here's an image that I hope that clarifies my idea.
我已经完成了一个使用 TreeViewer 和复选框创建自定义图形的界面。基于“邻接表”的想法。如果您选中了“根”顶点的复选框,它会使其与另一个顶点相邻,如果您只希望几个顶点相邻,那么您可以单独选择每个顶点。我已经为 Java 开发了这个,但我相信它也可以满足您的目的。这是我希望澄清我的想法的图像。
回答by Ash Blue
This topic is quite complicated, but if you want a nice repository of starter scripts check out this forum thread on Unity's official site http://forum.unity3d.com/threads/simple-node-editor.189230/
这个话题相当复杂,但如果你想要一个不错的启动脚本库,请查看 Unity 官方网站上的这个论坛主题http://forum.unity3d.com/threads/simple-node-editor.189230/
*Update: Someone has posted a complex tutorial series, heavily detailing how to create exactly what you've described. Enjoy https://www.youtube.com/watch?v=gHTJmGGH92w.
*更新:有人发布了一个复杂的教程系列,详细介绍了如何准确地创建您所描述的内容。享受https://www.youtube.com/watch?v=gHTJmGGH92w。
Edit: I've written a fully functioning Unity graph editor in a GitHub repo. Primarily focused on skill trees. It isn't perfect, but demonstrates what a fully functioning graph editor could look like. Source code in the following link.
编辑:我在 GitHub 存储库中编写了一个功能齐全的 Unity 图形编辑器。主要集中在技能树上。它并不完美,但展示了功能齐全的图形编辑器的外观。以下链接中的源代码。
回答by user999913
You are wrong dude. Everything you see in UnityEditor must have code somewhere. Your MecanimEditor is in namespace UnityEditor.Graphs.AnimationStateMachine.
你错了伙计。您在 UnityEditor 中看到的所有内容都必须在某处有代码。您的 MecanimEditor 位于命名空间 UnityEditor.Graphs.AnimationStateMachine 中。
Extend GraphGUI found in UnityEditor.Graphs. This class is responsible for drawing graph.
扩展 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{
}
}
Create new EditorWindow.
创建新的编辑器窗口。
public class GraphEditorWindow : EditorWindow
{
static GraphEditorWindow graphEditorWindow;
Graph stateMachineGraph;
GraphGUIEx stateMachineGraphGUI;
[MenuItem("Window/Example")]
static void Do ()
{
graphEditorWindow = GetWindow<grapheditorwindow> ();
}
....
Create Graph structure. It will contains nodes and edges between nodes.
创建图形结构。它将包含节点和节点之间的边。
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;
Draw Graph.
绘制图形。
void OnGUI ()
{
if (graphEditorWindow && stateMachineGraphGUI != null) {
stateMachineGraphGUI.BeginGraphGUI (graphEditorWindow, new Rect (0, 0, graphEditorWindow.position.width, graphEditorWindow.position.height));
stateMachineGraphGUI.OnGraphGUI ();
stateMachineGraphGUI.EndGraphGUI ();
}
}
Override NodeGUI or EdgeGUI for more styling and drawing control. Copy paste code from UnityEditor.Graphs.AnimationStateMachine.GraphGUI styling done in NodeGUI and EdgeGUI.
覆盖 NodeGUI 或 EdgeGUI 以获得更多样式和绘图控制。从 UnityEditor.Graphs.AnimationStateMachine.GraphGUI 样式中复制粘贴代码,在 NodeGUI 和 EdgeGUI 中完成。

