Как написать графический редактор для структур Graph или Tree

Unity3D Mecanim Анимационная система имеет пользовательский EditorWindow, который позволяет определять дерево (в данном случае смешанное дерево). GUI.

Похоже:

enter image description here

Он предлагает возможность создания узлов (состояний) и подключения их (переходов).

Теперь я разрабатываю некоторую структуру диаграмм и древовидных структур, и я хотел бы написать расширение редактора, чтобы позволить игровому дизайнеру заполнить эти структуры.

Я хочу, чтобы большинство из них воссоздало именно EditorWindow, как и аниматор Mecanim (рисунок выше).

Мой вопрос: есть ли какие-либо доступные компоненты, которые я могу использовать для такой задачи? Есть ли встроенный класс, используемый для рисования и соединительных ящиков и стрелок? Или мне нужно полностью написать элементы GUI?

Ответ 1

Я не просил "найти инструмент, библиотеку или любимый ресурс вне сайта". Я хотел бы знать, как воспроизводить графический редактор Mecanim с использованием API Unity3D или некоторых доступных компонентов, предоставленных самим движком (извините, если вопрос не был ясен).

Вот мой ответ:

Нет, нет доступного компонента, который можно использовать для рисования такого графика, но его довольно легко написать. Вот фрагмент с простым примером, используя draggable 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();
    }
}

Ответ 2

Ты ошибаешься, чувак. Все, что вы видите в UnityEditor, должно иметь код где-то. Ваш MecanimEditor находится в пространстве имен UnityEditor.Graphs.AnimationStateMachine.

Расширьте GraphGUI, найденный в UnityEditor.Graphs. Этот класс отвечает за рисование графика.

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.

Ответ 3

Этот вопрос довольно сложный, но если вам нужен хороший репозиторий стартовых скриптов, посмотрите этот форум на официальном сайте Unity http://forum.unity3d.com/threads/simple-node-editor.189230/

* Обновление: кто-то разместил сложную серию учебников, в которой подробно описывается, как создать то, что вы описали. Наслаждайтесь https://www.youtube.com/watch?v=gHTJmGGH92w.

Изменить: я написал полностью функционирующий графический редактор Unity в репозитории GitHub. Основное внимание уделяется деревьям навыков. Это не идеально, но демонстрирует, как может выглядеть полноценный графический редактор. Исходный код в следующей ссылке.

https://github.com/ashblue/unity-skill-tree-editor

Ответ 4

Вы можете попробовать сделать объект для данных внутри каждого дерева объектов. Затем вы можете попробовать использовать System.Drawing для создания настраиваемого элемента управления (квадратные квадратики на картинке), а также использовать System.Drawing для создания этих стрелок для каждого древовидного объекта. убедитесь, что каждый DataObject имеет идентификатор и информацию, для которых должны указываться стрелки. Если вам нужна помощь по созданию настраиваемых элементов управления, я использовал этот учебник на YouTube в прошлом.

Ответ 5

Я создал интерфейс для создания собственных графиков с помощью TreeViewer и checkbox. Основана на идее "список смежности". Если у вас установлен флажок "root" vertex, он делает его смежным с другой вершиной, если вы просто хотите, чтобы несколько вершин были смежными, тогда вы выбираете каждую отдельную сепал. Я разработал это для Java, но я считаю, что он также может работать для вашей цели. Вот изображение, которое, я надеюсь, прояснит мою идею.

http://i.stack.imgur.com/3PhT9.jpg