Siccity / xNode

Unity Node Editor: Lets you view and edit node graphs inside Unity
MIT License
3.26k stars 581 forks source link

Pressing Play unloads scene graph from editor window #272

Open Siccity opened 4 years ago

Siccity commented 4 years ago

Reproduction steps: 1) Add SceneGraph component to a gameObject in scene 2) Create and open graph on SceneGraph 3) Press play

Ayfel commented 3 years ago

Any idea how to fix this or the cause?

EmreDogann commented 11 months ago

This may be the same issue, but when I exit play mode, the editor window goes blank. After looking through the code a little, I found that it was because the NodeGraph instance that NodeEditorWindow holds onto gets lost/is null after exiting play mode. Because I'm using a scene graph, I'm assuming this is because Unity destroys the NodeGraph instance it created for play mode and reloads the edit mode NodeGraph, but NodeEditorWindow doesn't get updated with this edit mode instance. My solution, which is a little hacky, is as follows:

In NodeEditorGUI.cs

protected virtual void OnGUI()
{
    Event e = Event.current;
    Matrix4x4 m = GUI.matrix;

    // Fix for Editor Window going blank on play mode exit. Find the edit mode instance of NodeGraph.
    if (graph == null)
    {
        if (!graphFindAttempted && !OnOpen(graphInstanceID, 0))
        {
            graphFindAttempted = true;
            return;
        }

        if (graphFindAttempted)
        {
            return;
        }
    }
    else
    {
        graphFindAttempted = false;
    }

    ValidateGraphEditor();
    Controls();

    ...
}

graphFindAttempted is just a safety feature to make sure we are not constantly trying to open the editor window if we cannot find the NodeGraph.

In NodeEditorWindow.cs

...
public Dictionary<Node, Vector2> nodeSizes { get; } = new Dictionary<Node, Vector2>();
public NodeGraph graph;
public int graphInstanceID; // <--- Add this field to the class.
...
public static NodeEditorWindow Open(NodeGraph graph)
{
    if (!graph)
    {
        return null;
    }

    NodeEditorWindow w = GetWindow(typeof(NodeEditorWindow), false, "xNode", true) as NodeEditorWindow;
    w.wantsMouseMove = true;
    w.graph = graph;
    w.graphInstanceID = graph.GetInstanceID(); // <--- Also add this line to Open().

    return w;
}

While scene references in editor windows might get lost on playmode enter/exit, the actual instanceIDs of those references stay the same from what I found. So, we can use this instanceID to relocate the edit mode instance of the NodeGraph.

This solution fixed it for me. If anyone has a more elegant way of solving this, let me know!