Search Unity

[Demo] Relations inspector [Asset]

Discussion in 'Works In Progress - Archive' started by seldom, Feb 2, 2015.

  1. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    Edit: discussion moved to the release thread

    Hello.

    I‘m working on an editor extension that visualizes relations between any kind of project data. It‘s called Relations inspector, and produces graphs like these:



    On the left you see scene hierarchy relations between a GameObject and its children and components. In the center you see C# classes inheriting from Unity's Object type. On the right is a small social network. Here's a 2 minute video introduction, which looks awfull in anything but 720p:




    Just like Unity‘s inspector, it allows the user to view and modify data. However, instead of focusing on properties of one object, it‘s concerned with relations between objects. Many existing graph editors serve the same purpose, usually for a specific domain like animation states, behaviour trees, tech trees or dialog graphs. The relations inspector is another such tool, except its domain specific code is supplied by you, similar to writing a custom inspector.

    Such a backend class tells the tool which object relations to display, and which editing operations are allowed. The tool then takes care of building the graph, layout, navigation and editing. It is not restricted to GameObjects or Unity Objects, you can also feed it with xml entities, data from other editor windows or even runtime data in playmode.

    Links:
    Short user manual
    Intro to backend development
    Twitter

    The demo is not restricted in functionality, but it‘s very sleepy and requires many a naptime.
    I hope you like.
     

    Attached Files:

    Last edited: Jan 29, 2016
    Kropti67 and rakkarage like this.
  2. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    I'm working on communication between Unity extensions. Here's a dummy window that doesn't depend on the Relations inspector, but uses it for graph drawing when it can find it:
    https://gfycat.com/WetRedBettong
     
    Kropti67 likes this.
  3. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    Improved the type hierarchy example: sub- and supertypes are shown in the same graph. Code, and short demo video:
     
    Last edited: Feb 5, 2015
    Kropti67 likes this.
  4. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    Last edited: Feb 15, 2015
    Kropti67 likes this.
  5. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    Finished another example use case, this one is for Unity's roguelike tutorial project. I introduced level types, each with their own number of enemy/food/wall objects, to get a less monotone game progression. The relations inspector is used to edit the transitions between level types.
    Here is the full thing.
     
    Kropti67 likes this.
  6. Kropti67

    Kropti67

    Joined:
    Mar 4, 2015
    Posts:
    4
    Awesome. Great idea that will save S***load of time!
     
  7. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    Thank you!
    Since the last update I've been working on Unity 5 compatibility and smoothed the zooming as well as the layout steps. Best shown in moving pictures:
     
  8. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    Looks nice and quite useful. What are your plans for it? AssetStore?
     
  9. vicenterusso

    vicenterusso

    Joined:
    Jan 8, 2013
    Posts:
    130
    I don't understand few points of your project:

    1) I can make relations between gameobjects (if backend allows it) and them they become parent-children? Can this be changed? I don't want to mess with the hierarchy.

    2) Can I save the whole diagram?

    3) How can I queue that diagram at runtime?
     
  10. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    Thank you. There will be an asset store version soon, with source code included. I'll also keep the demo updated and feature-complete.

    I assume you are referring to this example. Yes, you can handle an added relation in any way you like. The example allows you to modify the scene hierarchy, that's why it is changing the transform parent. Otherwise there is no need to involve it.

    Lets say you have object for keys and doors and want to edit the unlocking relation between them. In that case, when a new relation is added, you'll want to set the door reference of a key object. Something like this:

    Code (CSharp):
    1.  
    2. public override void CreateRelation(GameObject source, GameObject target, string tag)
    3. {
    4.   // link key to door
    5.   var key = source.GetComponent<Key>();
    6.   var door = target.GetComponent<Door>();
    7.   if (key != null && door != null)
    8.       key.door = door;
    9.  
    10.   api.AddRelation(source, target, tag);
    11. }
    Does it store the node locations? No. Unlike other node-based editors, it uses automatic node positioning. That will give you an instant good layout in most cases, and it won't choke when your data was changed outside the window. Of course you can move nodes around if you like.

    No stored node locations.. just drag your data into the window and watch it unfold.
     
  11. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    "with source code included" -- Good. Was going to suggest that, since dev-heavy tools like this one make much more sense if people are able to iterate on it and change the parts they don't like.

    @vicenterusso, "How can I queue that diagram at runtime?" -- I think what you mean is "how can I traverse the graph at runtime", and I suppose the thing is: you visualize/build any kind of graph which is then stored in the editor anyways, the Relations Inspector is merely a way of viewing it and in some cases more comfortable/easier/faster editing. @seldom, please correct me if I'm wrong.

    @seldom, What pricing are you aiming for?
     
  12. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    Sorry for double-posting, but I played around a bit and thought I should make a separate post for that.

    I strongly advise for allowing custom, saveable node layouts. If something changes in the structure, you could just remove/add those new parts and re-layout them (fixing everything hand-moved) and/or make a re-layout button for automatic adjustment. There are many cases where automatic layouting can never reach a suitable quality or a state that is sufficient for a human - e.g. with many cyclic references.

    Example, auto-generated:
    upload_2015-8-31_0-38-36.png
    Same thing with circles:
    upload_2015-8-31_0-39-7.png

    How I as a human would layout this structure (and of course it should appear everytime I want to view any of the contained objects):
    upload_2015-8-31_0-41-45.png

    Of course this layout would be auto-generatable with the correct algorithm, but that's not the point - humans like moving things around and sort them to their liking, and I think that a relations viewer should support that instead of solely relying on its own algorithms.

    (I played around with the API and made a Physics Structure Backend, which shows the complete physics tree of something (colliders, joints, child colliders and so forth). Btw., this was not possible using GetRelated/GetRelating as those seem to not be recursive (?), so I built the whole graph in the Init method using the api directly.)
     
    seldom likes this.
  13. vicenterusso

    vicenterusso

    Joined:
    Jan 8, 2013
    Posts:
    130
    Exactly. I want to setup relations and check them at runtime. Another solution that might work too is arrange all nodes and each action (create relation, delete relation, etc) reflects directly on the component value on inspector. That way the relation is set in real time. And when I load the graph again, it reads the whole relations already set and builds the graph. I don't know if I made myself clear :p
     
  14. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    I agree with you that a hybrid between auto- and manual layout would work better, mainly for cases where you want to inspect the same graph repeatedly. Having to adjust the auto-layout over and over will get old quickly. I myself haven't had much frustration with that, but I see it can be inconvenient.

    Wow, your physics backend looks really nice. The circles screenshot gives me the mental image of an elaborate jack-in-the-box. GetRelated/GetRelating are used recursively, so they should work for your backend. Maybe your Init() didn't return any root nodes? That would have created an empty canvas.
    Did you find it difficulty to implement? Were the docs sufficient?

    Regarding pricing on the store, I'm thinking $30.

    Ok now I get it :)
    felix' answer is correct, you can think of the Relations inspector as a view on your data. The relations graph is not stored anywhere as a separate file, it is derived from your data, and any modifications you make to the graph are applied to your data immediately. In other words, the solution you're proposing is exactly how the tool works. In your custom backend class you define what parts of your data should be shown by the graph and how to apply graph edits to your data. Does that help?
     
  15. vicenterusso

    vicenterusso

    Joined:
    Jan 8, 2013
    Posts:
    130
    Yes it helps! But the layout-saving feature might be a BIG plus for your project :)
     
  16. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    Tried to build another backend, this time for visualizing PlayMaker connections.

    For simple ones, it does indeed work as intended and is already quite helpful (albeit multi-arrow positioning might need some more work, especially for even more of them):
    screenshot.2015-09-01 11.38.48.png

    However, for more complex ones I always get an error from deep in RI:
    Code (csharp):
    1. ArgumentException: Subject does not fill the expect role in edge.
    2. RelationsInspector.EdgeSet`2[System.Object,RelationInfo].Add (RelationsInspector.Edge`2 edge)
    3. RelationsInspector.Graph`2[System.Object,RelationInfo].AddEdge (RelationsInspector.Edge`2 edge)
    4. RelationsInspector.GraphWithRoots`2[System.Object,RelationInfo].AddEdge (RelationsInspector.Edge`2 edge)
    5. RelationsInspector.GraphBuilder`2[System.Object,RelationInfo].Build (IEnumerable`1 roots, RelationsInspector.GetRelations GetRelated, RelationsInspector.GetRelations GetRelating, Int32 recursionSteps)
    6. RelationsInspector.Workspace`2[System.Object,RelationInfo].InitGraph (System.Object[] targets)
    7. RelationsInspector.Workspace`2[System.Object,RelationInfo]..ctor (System.Type backendType, RelationsInspector.RelationsInspectorWindow editorWindow, System.Object[] targets)
    8. System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:513)
    9. Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    10. System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:519)
    11. System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:528)
    12. System.Activator.CreateInstance (System.Type type, BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Activator.cs:338)
    13. System.Activator.CreateInstance (System.Type type, BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Activator.cs:274)
    14. RelationsInspector.RelationsInspectorWindow.CreateWorkspace ()
    15. RelationsInspector.RelationsInspectorWindow.InitWorkspace ()
    16. RelationsInspector.RelationsInspectorWindow.OnTargetChange ()
    17. RelationsInspector.RelationsInspectorWindow.SetTargets (System.Object[] targets)


    Any idea what might be causing these? I'm not using the api here, just yielding objects from GetRelated.

    EDIT: @seldom, seems you have PMs disabled? Would like to send you one.
     
    Last edited: Sep 1, 2015
  17. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    PMs should be enabled now. That bug happens during graph construction, an edge is added to the wrong node. I'll look into it.
    This is another interesting RI application, I hadn't thought of using it with playmaker.
     
  18. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    One more update before the release. I added layout saving, and then some.

    Changes since second demo:
    • added layout saving
    • added history (and navigation)
    • added support for arbitrary graph sizes via folding/expanding of nodes
    • added autobackend. A graph is generated from the fields you put attributes on. Similar to default inspector.
    • added example backend that clusters scene objects by tag
    • tree layout is now applicable if the graph consists of multiple trees
    • tree layout can be rotated
    • smoother layout transitions
    • x,y dimensions can be zoomed separately
    • settings and skin are now accessible via menu
    • backend interface changes (Awake, OnUnitySelectionChange, OnCommand)
    • bugfixes, polish, documentation

    I've also reworked the asset reference backend, it now shows the full path from the target asset to the scene objects that reference it. It got a twin too: a dependency backend, which shows all objects referenced by the target.

    edit: added type hierarchy backend to examples
    edit: demo5 fixes a bug in one of the example backends
     

    Attached Files:

    Last edited: Dec 30, 2015
  19. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
  20. ChiuanWei

    ChiuanWei

    Joined:
    Jan 29, 2012
    Posts:
    131
    i wanna know this assets how to work with playmaker. thanks :)
     
  21. seldom

    seldom

    Joined:
    Dec 4, 2013
    Posts:
    118
    I haven't made any plugin for playmaker yet. Felix posted about one, but I don't know what that does. Is there anything in particular that you want to visualize?
     
  22. Lanslot

    Lanslot

    Joined:
    Nov 18, 2016
    Posts:
    37
    Can it to show class diagram?