【问题标题】:How to write a GUI editor for Graph or Tree structures如何为图形或树结构编写 GUI 编辑器
【发布时间】:2013-07-11 12:14:13
【问题描述】:

Unity3DMecanim 动画系统有一个自定义的 EditorWindow,它允许通过 GUI 定义一棵树(在本例中为混合树)。

看起来像:

它提供了创建节点(状态)和连接它们(转换)的可能性。

现在,我正在开发一些图形和树结构,我想编写一个编辑器扩展,以便让我的游戏设计师填充这些结构。

我最想重新创建一个 EditorWindow,就像 Mecanim 动画师(上图)一样。

我的问题是:是否有任何可用的组件可用于此类任务?是否有用于绘图和连接框和箭头的内置类?或者我需要自己编写完整的 GUI 元素?

【问题讨论】:

  • 我不知道这是否对您有很大帮助,但举个例子,here is a nice post 我曾经在我的编辑器窗口中做贝塞尔线。这是一个很好的例子。
  • @Jerdak:谢谢.. 非常有趣。我去看看。
  • @Jerdak 也感谢您的链接!出于兴趣,我正在看这个,因为我想要一些与我的状态机的 MechanimEditor 非常相似的东西。
  • 我看到的只有线条、箭头和文本框。所以你有它们的集合,你需要写一些可以创建和存储这样一个集合的东西
  • @Jerdak:我找到了一种在编辑器中绘制贝塞尔线的更简单方法。如果您将 Handles.DrawBezier 与 Handles.BeginGUI/EndGUI 放在一起,您可以使用统一函数在编辑器窗口中绘图。我很快就会发布一个sn-p。

标签: c# unity3d


【解决方案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

        【讨论】:

          猜你喜欢
          • 2021-08-25
          • 2012-04-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-02
          • 2021-04-20
          相关资源
          最近更新 更多