web-dev-qa-db-fra.com

Comment écrire un éditeur GUI pour les structures de graphique ou d'arbre

Unity3D Le système d'animations Mecanim possède un EditorWindow personnalisé qui permet de définir un arbre (un arbre de mélange dans ce cas) une interface graphique complète.

On dirait:

enter image description here

Il offre la possibilité de créer des nœuds (états) et de les connecter (transitions).

Maintenant, je développe un graphique et une structure arborescente et je voudrais écrire une extension d'éditeur afin de permettre à mon concepteur de jeu de remplir ces structures.

Je veux que la plupart recréent exactement un EditorWindow comme celui de l'animateur Mecanim (figure ci-dessus).

Ma question est: existe-t-il des composants disponibles que je peux utiliser pour une telle tâche? Y a-t-il une classe intégrée utilisée pour les boîtes de dessin et de connexion et la flèche? Ou dois-je écrire complètement les éléments de l'interface graphique par moi-même?

28
Heisenbug

Je ne demandais pas "pour trouver un outil, une bibliothèque ou une ressource hors site préférée". Je voudrais savoir comment reproduire un Mecanim comme un éditeur de graphes en utilisant Unity3D API ou certains composants disponibles fournis par le moteur lui-même (désolé si la question n'était pas claire).

Voici ma réponse:

Non, il n'y a pas de composant disponible utilisable pour dessiner ce type de graphique, mais il est assez facile d'écrire le vôtre. Voici un extrait avec un exemple simple utilisant draggable GUI.Window pour représenter les nœuds et Handles.DrawBezier pour dessiner les bords:

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();
    }
}
16
Heisenbug

Vous vous trompez mec. Tout ce que vous voyez dans UnityEditor doit avoir du code quelque part. Votre MecanimEditor est dans l'espace de noms UnityEditor.Graphs.AnimationStateMachine.

Étendre GraphGUI trouvé dans UnityEditor.Graphs. Cette classe est chargée de dessiner un graphique.

using System;
using UnityEditor;
using UnityEngine;
using UnityEditor.Graphs;
using System.Collections.Generic;

namespace ws.winx.editor.components
{
 public class GraphGUIEx:GraphGUI{


 }

}

Créez une nouvelle EditorWindow.

public class GraphEditorWindow : EditorWindow
 { 
  static GraphEditorWindow graphEditorWindow;
  Graph stateMachineGraph;

  GraphGUIEx stateMachineGraphGUI;

  [MenuItem("Window/Example")]
  static void Do ()
  {
   graphEditorWindow = GetWindow<grapheditorwindow> ();
  }

....

Créer une structure graphique. Il contiendra des nœuds et des arêtes entre les nœuds.

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;

Dessiner un graphique.

void OnGUI ()
  {

   if (graphEditorWindow && stateMachineGraphGUI != null) {
    stateMachineGraphGUI.BeginGraphGUI (graphEditorWindow, new Rect (0, 0, graphEditorWindow.position.width, graphEditorWindow.position.height));
               stateMachineGraphGUI.OnGraphGUI ();


    stateMachineGraphGUI.EndGraphGUI ();

   }
  }

Remplacez NodeGUI ou EdgeGUI pour plus de contrôle de style et de dessin. Copiez le code de collage à partir du style UnityEditor.Graphs.AnimationStateMachine.GraphGUI effectué dans NodeGUI et EdgeGUI.

13
user999913

Ce sujet est assez compliqué, mais si vous voulez un joli référentiel de scripts de démarrage, consultez ce fil de discussion sur le site officiel d'Unity http://forum.unity3d.com/threads/simple-node-editor.189230/

* Mise à jour: quelqu'un a publié une série de didacticiels complexes, détaillant en détail comment créer exactement ce que vous avez décrit. Profitez https://www.youtube.com/watch?v=gHTJmGGH92w .

Edit: j'ai écrit un éditeur de graphes Unity pleinement fonctionnel dans un dépôt GitHub. Principalement axé sur les arbres de compétences. Il n'est pas parfait, mais montre à quoi pourrait ressembler un éditeur de graphique pleinement fonctionnel. Code source dans le lien suivant.

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

5
Ash Blue

Vous pouvez essayer de créer un objet pour les données à l'intérieur de chaque objet arborescent. Ensuite, vous pouvez essayer d'utiliser System.Drawing pour créer un contrôle personnalisé (cases carrées dans l'image), également utiliser System.Drawing pour créer ces flèches pour chaque objet d'arborescence. assurez-vous que chaque DataObject possède des ID et des informations indiquant où les flèches doivent pointer. Si vous avez besoin d'aide pour créer des contrôles personnalisés, j'ai utilisé ce tutoriel sur YouTube dans le passé.

0
McSwaggens