Seneral / Node_Editor_Framework

A flexible and modular Node Editor Framework for creating node based displays and editors in Unity
https://nodeeditor.seneral.dev
MIT License
2.01k stars 414 forks source link

How NodeCanvas ( Nodes with Inputs/Outputs ) should be loaded in Runtime/Compiled #75

Closed MohHeader closed 8 years ago

MohHeader commented 8 years ago

Hi,

I am really happy to discover this gem, Very nice, very clean & easy to customize.

I just got one main issue, How to load the NodeCanvas in Compiled game, i.e. to use the nodes logic in the game.

So far I get it to work in UnityEditor through :

NodeCanvas x = NodeEditorFramework.NodeEditorSaveManager.LoadNodeCanvas("Assets/Plugins/Node_Editor/Resources/Saves/"+Conversation.name+".asset");
NodeEditor.RecalculateAll(x);

But that won't work in Compiled versions.

Any advice ?

Thanks

MohHeader commented 8 years ago

Also wanted to mention that ( in case it would help )

that my Calculate () in Custom Node is just returning true

public override bool Calculate () {
    return true;
}
Seneral commented 8 years ago

Thanks for the feedback:)

I found that the file path preparation (that makes your input compatible with either AssetDatabase or Resources) and actual loading are inconsistent - the one uses AssetDatabase in playmode, the other Resources. But in a built, it should work.

So, please open ResourceManager.cs in Utility and check if replacing these first three functions works:

#region Common Resource Loading

/// <summary>
/// Prepares the path; At Runtime, it will return path relative to Resources, in editor, it will return the assets relative to Assets. Takes any path.
/// </summary>
public static string PreparePath (string path) 
{
    path = path.Replace (Application.dataPath, "Assets");
    #if UNITY_EDITOR
    if (!Application.isPlaying)
    {
        if (!path.StartsWith ("Assets/"))
            path = _ResourcePath + path;
        return path;
    }
    #endif
    if (path.Contains ("Resources"))
        path = path.Substring (path.LastIndexOf ("Resources") + 10);
    return path.Substring (0, path.LastIndexOf ('.'));
}

/// <summary>
/// Loads a resource in the resources folder in both the editor and at runtime. 
/// Path can be global, relative to the assets folder or, if used at runtime only, any subfolder, but has to be in a Resource folder to be loaded at runtime
/// </summary>
public static T[] LoadResources<T> (string path) where T : UnityEngine.Object
{
    path = PreparePath (path);
#if UNITY_EDITOR // In the editor
    if (!Application.isPlaying)
        return UnityEditor.AssetDatabase.LoadAllAssetsAtPath (path).OfType<T> ().ToArray ();
#endif
    throw new NotImplementedException ("Currently it is not possible to load subAssets at runtime!");
    // return UnityEngine.Resources.LoadAll<T> (path);
}

/// <summary>
/// Loads a resource in the resources folder in both the editor and at runtime
/// Path can be global, relative to the assets folder or, if used at runtime only, any subfolder, but has to be in a Resource folder to be loaded at runtime
/// </summary>
public static T LoadResource<T> (string path) where T : UnityEngine.Object
{
    path = PreparePath (path);
#if UNITY_EDITOR // In the editor
    if (!Application.isPlaying)
        return UnityEditor.AssetDatabase.LoadAssetAtPath<T> (path);
#endif
    return UnityEngine.Resources.Load<T> (path);
}

#endregion

Also, loading EditorStates will not work either, as currently they have to be fetched from the subAssets of the file and these are not accessible through Resources:/

Seneral

MohHeader commented 8 years ago

Thanks for your response,

Hmmmm, I am not sure,But now both Built version and Play in Editor raise the exception :

    throw new NotImplementedException ("Currently it is not possible to load subAssets at runtime!");

I think that is what you want to say, I can't use the Nodes in Runtime ?

I am really sorry, But I am totally confused, because I thought that the CanvasNode is ready to be used in Runtime.

Please excuse my ignorance, but if it is not available in run-time Then it is still in experiment phase ? ( i.e. I can't use it's results yet in game logic ,, true ? )

Thanks

Seneral commented 8 years ago

You can use it, but whatever method your using, you can't yet load editor states. So you need to make sure nothing will trigger Resources.LoadResources ;) Because that requires subAssets to work and this is not possible at runtime... It is possible to fix that by simply make the canvas reference the editor states, because the canvas is easily retrievable as it's the main asset in the file.

Seneral commented 8 years ago

This is fixed in the newest commit 23c875b to the develop branch:) Please read notes, they will tell you what works and what not at runtime!