Search Unity

Simple node editor

Discussion in 'Immediate Mode GUI (IMGUI)' started by unimechanic, Jul 5, 2013.

  1. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Thanks, remember an issue similar to that, but I'm quite sure I fixed it. Will take another look at that, no promise on when I find time though. Can you create an issue on Github for it please?
    Shouldn't be too hard to fix though if you know the code already:)
    Seneral
     
  2. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    Yeah I will create a github issue. Perhaps I will start contributing since I am using it now. I noticed with dialog nodes, perhaps all nodes - not sure, have "back link" ports which can only have one connection? Is there any reason why an input can't accept any number of connections? Perhaps there's something I can change which limits this.
     
  3. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    After digging just a little I see the knobs seem to be set up to accept numerous connections. Odd that when editing if I try to connect more than one node back to a specific node, all but one connection remains.

    [edit]Found the cause, the connection know attribute wasn't set up to support enough.

    I don't have time to get into github atm but I noticed the constructor for the attribute argument set I needed was oddly transposed compared to the one he was using originally.


    Code (CSharp):
    1.         public ConnectionKnobAttribute(string name, Direction direction, string styleID, ConnectionCount maxCount, NodeSide nodeSide, float nodeSidePos = 0) : base (name, direction, styleID)
    2.         {
    3.             Setup (maxCount, nodeSide, nodeSidePos);
    4.         }
    Should be:

    Code (CSharp):
    1.         public ConnectionKnobAttribute(string name, Direction direction, string styleID,  NodeSide nodeSide, float nodeSidePos = 0, ConnectionCount maxCount = ConnectionCount.Single) : base (name, direction, styleID)
    2.         {
    3.             Setup (maxCount, nodeSide, nodeSidePos);
    4.         }
    The transposition of the arguments made it hard to read which one was right in VS intellisense. Or something to that effect.
     
    Last edited: May 26, 2018
  4. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Well there's no way to edit Multi-Multi connections right now, due to the way you remove connections - you drag the connection of of it's target port. Can't do that when both ports have other connections.
    This is just a remainder of the initial version only suited for calculation - there, it made no sense to have multiple inputs to one knob.
    There are concrete plans though, we settled on deleting connections by clicking on them, which needs a hit detection, but is the most intuitive. Not implemented though, if you are interested in that, you can give it a try:)
    Seneral
     
  5. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    Yeah that's fine, I was actually interested in Single -> Multi which I sorted out. Seems the default setup in the dialog system example was single for all ports.

    I have to work with what's in the system for now, but at some point I will undoubtedly make additions to the core node framework and when that time comes I'll get involved in the github project more. I appreciate that you're still invested in this, pretty cool. Nice work to the group.
     
  6. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    Seneral, I would appreciate some help on the Canvas Types stuff, and also make sure that it is OK to use your
    framework in a sold asset on the Asset Store.

    I am developing a dialogue system that does much more than dialogue, and so I have a main window (much like Dialogue System For Unity) that will edit scene data(for campaigns or stuff), quests, variables, dialogue, etc. That wouldn't be a problem, except that I want the ability to switch between the different editors(in the same main window) depending on the toolbar's selected index. E.g. I want to switch from the dialogue node editor to the quest editor, so I click the "Quests" toolbar button, switching from the dialogue node editor to the quest editor, and thus switching canvas types. Like below:
    forum1.PNG
    (Please excuse how ugly this is, it is just a draft)
    I know this is possible, but the problem is that I want the nodes to be saved when I switch. So if I switched from the dialogue node editor to the quest editor, when I switch back, the nodes are still there, and vice versa. And some of the windows won't be node editors. I know there are many workarounds to this, and if that is what I have to do, that is totally cool with me. It is a great asset.

    Please tell me if it is alright to use your framework on the Asset Store too. I read the license, so I would assume so, but I just want to make sure. I don't mind giving you credit at all, in fact I think I would anyway, because this framework is SO cool.
     
  7. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Sounds good to me, I don't have the time anymore to really invest into it like I used to unfortunately, but I'll help out since I know it basically as the only one in and out:)
     
  8. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Ya sure, no problem using it on the AS, just include the license. Not a big deal really from my side:)

    So you have two canvas types, and you want to switch between them. Now, is that switch something you expect to happen often (as in a editing mode switch) or is it more of a conversion between types?
    First case, I would recommend embedding both in one type if possible, not worth the hassle.

    Second case, an explicit conversion might be more appropriate since it will require to make a new canvas [NodeCanvas.CreateCanvas<Type>] and copy over the nodes. Now, if you need to have the old canvas still intact and working, you need to duplicate the nodes explicitly (more on that in a sec). If you just need to switch types and don't care about the old type any longer, you can just assign the nodes and groups array [canvas.nodes/groups] and some extra data [canvas.saveName/savePath/livesInScene/...] to the new canvas and dispose of the old canvas.
    Also, depending on which needs the canvas types have, you might need to filter the nodes and/or manage eventual root nodes obviously. Depends on your setup.
    If you need to copy the nodes over (keeping both canvases intact), you need to first create a working copy of the original canvas [NodeEditorSaveManager.CreateWorkingCopy] (which will duplicate the whole ScriptableObject structure, keeping references intact) and then do the same as already mentioned (create a new canvas, assign the node array of the working-copy-canvas to it).

    Hope that's what you wanted.
    Seneral
     
  9. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    I notice that enum popups and things don't render in the right place. Was trying to digest how the drawing is done as I believe the GUI can be provided a matrix to control drawing and I wonder if this is utilized somewhere. The zooming, however that is handled, isn't correct.

    [edit]
    I see there's quite a lot of scaling code. Perhaps someone can hint at anything they know about this that might need to change to have enum popups and the like render properly.

    [edit 2]

    I wonder if this is somehow related?
    Code (CSharp):
    1.             // Because I currently found no way to actually scale to a custom pivot rather than (0, 0),
    2.             // we'll make use of a cheat and just offset it accordingly to let it appear as if it would scroll to the center
    3.             // Note, due to that, controls not adjusted are still scaled to (0, 0)
    4.             Vector2 zoomPosAdjust = rect.center - screenRect.size/2 + zoomPivot;
    5.  
     
    Last edited: May 27, 2018
  10. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    Thanks! I appreciate your response. And thank you for the ability to use this asset in this capacity.

    I'm pretty sure it would be the first case. The setup is slightly still in the air, but basically, I will just have (to my knowledge so far) a setup where the quests are edited with the node editor, and the dialogue will be edited with a node editor, both in the same window. I will have to see about putting both types in the same type, I didn't even have the types up and running yet lol. So I will have to implement some things, and I will get back with you. :)
     
  11. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    Ok so some clarification here, sorry I wasn't clear the first time.

    I don't need to swap nodes with the canvases, I just need the nodes to be saved so that when I swap from the quest editor, to the dialogue editor, the nodes from the dialogue editor pop up, and when I switch back to the quest editor, the quest nodes I was editing before will pop up. I just need the respective canvases to save their nodes so if I switch to another canvas, the nodes are saved.

    This is sounding more and more like I will have to use files for this, which is ok.
    But I will be editing a database with these editors and I'm worried it could become clumsy, so I wouldn't prefer it. However I am cool with whatever I need to do.
     
  12. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    ya, you got it, except we can do nothing about it.
    Scaling is complex because it is half-heartedly implemented on Unity's side (GUI.matrix).

    The advanced code (GUIScaleUtility) is all about fixing a few of the most severe flaws, that is that clipping rects are not considered. Basically, your unscaled window is rendered and THEN scaled, in lot's of cases that means unwanted clipped nodes right inside the window.

    One other flaw is unfortunately unfixable, that is that the popups simply ignore scaling, so scaled controls won't account for it and the popups appear at unwanted positions. See no chance in unity fixing it anytime soon, so I had a replacement popup in development (you see it as the context menu). With a bit of further work it can be used for popups like enums.
    Hope that helps.
     
  13. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    Cheers, at least I know not to worry about it now. Will look into your other popup code.
     
  14. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Ah, makes more sense lol.
    No, you just need two NodeEditorUserCaches. These are wrappers around the canvas that help managing the lifetime of the canvases, etc. Then theres NodeEditorInterface which is a wrapper mapping the toolbar UI to the user cache. If you look in the window code, you have one usercache and one interface object.

    You could get away with two usercaches for each respective canvas and a property with the current naming that switches between them based on the state. Additionally you would have to update the interface object to call into the current user cache (it keeps a reference to the current one). That would work since both canvases live in the memory.
    Also you might want to make sure that whenever the current usercache is referenced, you consider whether it needs to call it on both canvases or only the current one, and you may want to save the cache of the currently opened one before switching to the other canvas.

    One problem is the cache system, currently the opened canvas is periodically saved to a fixed path so it will reopen the last edit without the user needing to save. Since it is fixed, the two canvases will fight for that position (as in, if one is told to save cache, it will overwrite the cache of the other). The system was not created with two canvases explicitly in mind.

    There's a rather easy fix though, you can modify the NodeEditorUserCache to have two cache paths. Just search for "lastSession", and whenever it is inside a string (call to save, etc.), you can replace it with a new variable member and set that from the window, so you can set your quest user cache to "lastSessionQuest" and the other to "lastSessionDialogue".

    Hope that helps!
    Seneral
     
    KrytalityStudios likes this.
  15. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Alright, it's frustrating, but nothing we can do about it (to my knowledge).
    My popup system has a general core, OverlayGUI, which allows us to easily control focussed overlay controls that are by itself not affected by scaling, like popups. There is already a wrapper (begin/end calls) around each nodeeditor for the normal popup so we can easily add onto that. In the same file you see the PopupMenu which is a hierarchial context menu. You can extend or modify a copy of it completely to get started with enums.
    The only difference to the standard menus is (in theory) that you can explicitly control the positions, which is done in the GenericMenu class, also same file (see GUIScaleUtility.GUIToScreenSpace).
     
  16. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    Ok I'll give it a try! Thanks!
     
  17. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    What are your plans with the system Dmf. Sounds like you're trying to stitch a system for progression/dialog out using it. Sounds like we're on a similar path.

    I have very little experience in this are of things so getting basic ideas on structuring it has been an interesting challenge. I've mostly just spent time constraining my design options though, so even though I can't foresee how to solve all of the possible requirements, I still make some progress. Hope you're finding success.

    Largest portion of my focus so far has been in text presentation and capabilities of the dialog system as a whole. I just replaced my original backend which consisted of JSON data files exported from Twine with an extended version of the dialog node example. Before that I had built out a tag parsing setup where there are tags I can insert in dialog to control how display functions <p .3> = .3 second pause, <br> = jump or break point, where the user can skip forward by hitting a continue hotkey or something. <br 1.4> = a simillar break, but with a delay then auto progression. <cls> = clear screen, lets you flush the dialog display buffer. <fade .5> = fade text out over half a second and then do an automatic <cls>, etc.

    The next cool thing is integration with a LUA script interpreter in the backend, and you can write code right into your dialog <! cinematics.disableCharControls(true); > is an example of a code tag, within '<!' and '>' you can have arbitrary code execute. Those are inline command tags and execute when the code is hit in the dialog (our system outputs code in typewritter fashion). We also have attributes in those tags such as <! #pre ... > or <! #post ... >, this indicate non inline command tags, they execute either before text display starts or after it finishes.

    Overall I've been happy with the options it provides.
     
    Last edited: May 28, 2018
    KrytalityStudios and Seneral like this.
  18. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    My main goal is to be "the one stop tool for creating a story" (which is kinda marketing terms lol) but anyway, so the big goal is to combine a lot of different assets on the store (more on that in a minute) and make them work together to easily create story driven games, nonlinear or linear, FPS or RPG, horror or fantasy, whatever the game is I want to be able to reach the genre.

    The different kinds of tools I want to offer are things like:
    Node based dialogue system (looked hard at first but not now lol) with support for stuff like the usual response menus and dialogue lines, but also stuff like triggers and events within the dialogue, as well as Timeline and Cinemachine support and stuff like that.
    A node based quest editor like the dialogue editor with variables and stuff (have not been into this much so idk how all this will work).

    I do want to have an integration with Python much like your Lua integration. I'm still pretty early in the project like you, even though I've been doing this for a month or so, because I didn't know any editor scripting. So I spent some couple of weeks just getting my head wrapped around the system and learning editor scripting, and the next couple doing the actual implementation. I started doing some node editor stuff myself until discovering this node editor framework.

    Speaking of the Lua integration, I would love to know about how your Lua integration went and how you did it with this framework. I haven't got Iron Python yet, which is supposed to be a good interpreter for Python to C#, but I will likely tommorrow as I think it could be an integral component in my asset.

    If you would like to pm me I'll give you my email and we can talk about this. I love this kinda stuff!
     
  19. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    Btw I just changed my name to my "studio name" Krytality Studios. I don't really have a studio but anyway. Lol I may change it back.

    (Edit) it isn't working?? Anyway...
     
  20. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    I'll touch base with you at some point. I don't know if I'll be sharing my implementation details right now as I haven't decided if I'll be selling this tool or not and it sounds like we would be in competition if I do :p. Sounds interesting though, I don't have intention of combining asset store products any time soon so you have that angle XD.
     
    KrytalityStudios likes this.
  21. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    @Seneral I am implementing a new canvas type and was wondering what constitutes a recursion in the canvas and how it's actually handled when Node.AllowRecursion is true? The comment in the file implies a lot without defining it's terms.

    I was also interested in canvases having their own adjustable "global" fields which the user could modify. I could obviously let them edit those in the canvas asset inspector, but I'd like to add controls which would be visible directly in the node editor window if that canvas type is currently loaded.

    Cheers.
     
  22. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Hi,
    ya sorry, it's sort of an edge case I implemented for the sake of it but haven't actually touched on in a real world example due to the lack of actual use. Allow Recursion is per node, and allows the node to be in loops. That means you follow output-inputs that direction and you can end up at the same node. If atleast one node in a loop allows for loops, it is permitted (this leads back to the later discussed per-node escape condition).

    This is obviously not intended for stuff like calculation, so if any of the calculation nodes would allow that, the default calculater of the calculation canvas would crash.
    There are two occasions where enabling it makes sense: You have an own canvas traversal routine which does things differently as the default calculation routine (like temporal state stuff like in a quest or dialogue) or if one of your nodes actually has an escape condition so the loop is handled in a node.
    For the first case it would make more sense to make that a property of the canvas itself, but you can also just enable it on every one of your nodes.

    But I'm sure you would need to make your own canvas traversal algorithm either way, calculator is really unsuitable for quests/dialogue. Even more, you said you would only use the framework as an editor for your own backend, in which case you don't need ANY traversal (which is essentially a routine to update the canvas while it's being edited, used to update calculated values).
    Hope that makes sense.

    As for the canvas variables, sure, why not? Just overwrite DrawCanvasPropertyEditor in your custom canvas type to create GUI for it in the inspector.

    Seneral
     
  23. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    Lol ok that is totally fine, I'm glad it is working for you, and I hope it goes well!
     
  24. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    @Seneral Btw awesome support, thank you for sticking with this asset! Also on that note, if you give me some tips on how to save and reload canvases to a custom database, it would be appreciated.

    My issue with it is like this: I am gonna have dialogue, quests, and stuff so I have different databases, like a scene database (for missions and scene setup), a dialogue database, and for simplicity quest databases separate from the dialogue database (it was going to be a part of it). I would really like to have custom data preferably. And so at the moment the big issue that made me separate the dialogue database from the quest database is idk how to save two different canvases to the same database. The NodeEditorUserCache doesn't look capable of doing this, saving two different canvases to the same file, and I really would like some custom data in the database instead of just a canvas. So if I have to write another save manager or something, I guess I can, but I want to figure out the best approach for this, as that file is like 600 lines long lol.

    Some approaches I was thinking of were these:
    Heavily modify the NodeCanvasSaveManager and NodeEditorUserCache to read/write to a single custom database;
    Do the same but let there be a dialogue database, and a quest database separate from each other;
    Make a custom inspector for the canvas and change some data a bit.
    Make a database wrapper for the saved canvas somehow (which sounds appealing so please elaborate on this),
    which could involve some trickery but might be worth it?

    Just a thought off of my head and correct me if I'm wrong, but for simply writing and loading data to and from a database, I don't think that it would take 600 lines of code, as the NodeCanvasSaveManager is built to handle lots of special cases, so idk. Please tell me if possible how much code needs to be written for this.

    I really would just like to get this thing working as soon as possible lol! So your help is greatly valued on this.

    Thanks in advance!
     
  25. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Sure, no problem:) Hate dropping support until there are better alternatives that are established.

    Do you already have a plan on the structure of the database? E.g. is it a Json or XML text format to host the dialogue/quest data as previously mentioned? Or is it a centralized database in form of a scriptable object (SO) holding all quest/dialogue information of the game? Or any other combination?

    So, I do not recommend modifying the SO saving system at all. Reason for this being is that you might have two formats: The existing one for holding the canvas and your custom database only for the actual quest data (excluding editing information like node position, connections, extras, etc.).

    In that case, you could have a interpreter running alongside the the saving system (either using traversal system to enable realtime edits or alongside / injected into the save system, which would be more cumbersome during edit time).
    It would allow you to basically write in a centralized database, no matter the format, just with your own data without the extra node clutter. I could very well imagine this option, each canvas having an ID, writing into a centralized database (quest identified by ID) and updating that information in realtime.
    That would have the disadvantage of not allowing direct edits on the raw quest data as it will not reflect in the node canvas back, and having two save files / databases.

    If you want to fully replace the save format (and save all node specific stuff in your database, too), yes I would recommend writing an own manager just LIKE the existing save manger, just don't replace it. Then you can fully modify the user cache to use your new format. Depends how you would handle the cache/session save.

    Now, reading your answer again after writing this, I see your focus was more on combining quest and dialogue, which are two canvases, in one unified save file with extra data. Now, while it is technically possible to do that, and would also work best management wise (even with the split database idea that I like), it will indeed need some changes to the save manager to accept two canvases.
    That would mean you would need to make assumptions about these canvases (same save path, both in scene/asset, etc.), but it should be possible. But make sure to copy the function you want to modify and make a new override for it!
    Basically, save manager just dumps all SOs (nodes, knobs, etc..) into the same save file, and searches for the nodecanvas main object on load and uses it's references to load the associated SOs in the same file. You should be able to easily modify that to search for multiple canvases and load them, no serious complications there I think, except for slightly duplicated code...

    Long and complex one, hope it helps you:)
    Seneral
     
    KrytalityStudios likes this.
  26. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    Lol thanks so much I'm astounded!
    Lemme actually read this real quick.. Oh wait...
    Lol really ill get back in a sec
     
  27. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    Thank you!

    Ok so yes my database is a centralized SO that stores dialogue and quests, no fancy stuff here really so yea.

    I will have to see about the interpreter, sounds cool, and otherwise I will do the last option, also cool.

    Cheers
     
  28. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Well, if you go with the interpreter and canvas separated setup, you still have the option to combine both canvases in one file if you want. Just some thoughts on this. Combined file is just for the editor and for cleanliness I guess, so you don't have to load up both manually. The other is an actual implementation decision.
    Wish you luck, whichever you go with:)
     
    KrytalityStudios likes this.
  29. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    This might have come up previously, but I've noticed two things I would like to poke around at.

    1. there seems to be quite a bit of lag when the editor gains/loses focus, is there something happening in the background at those times?

    2. I noticed with some controls, the focus of which control is being utilized seems to not update in time for things like enum popups. I'll have more than one of my nodes in a canvas, click in an enum value in one I wish to change, and change it, then move onto a second node, clicking the enum popup to change it, and the alteration applies to the first node instead of the second node as I intended. So it seems the "Active node" isn't being updated immediately on clicking on a control from a different node, as I would like.

    Any thoughts on these issues would be appreciated, cheers.
     
  30. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Ya indeed, both have come up.
    First is caused by a cache save (the canvas is saved to disk), which prevents data loss in cases where there are no callbacks (like unity crash, even changing the scene by user would result in data loss without this).

    Second one is also kind of caused by the way the popups work. When you click on them, there's no way for the framework to know this UNTIL the popup is closed. Basically the click is catched and not let through by the popup. Sure, the actual error is caused by the framework, not fixed yet, basically a click on a node will cause it to be rendered in front of other nodes (last to be drawn), which makes sense when nodes overlap. This changes render order, and in combination with the popup click thing, it can cause unexpected control reordering so that unity associates the last node with the current popup. Just comment this code block which pushes the selected node in front, that should theoretically fix it.
     
  31. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    Nice thanks!

    So I've been poking around and it looks to me like the value returned by GetID in a node can be unique per node? For example, all of my dialog nodes don't HAVE to return dialogNode, do they? I was thinking about having the ID be a GUID instead so I could uniquely identify nodes. The code that calls it seems to think of it this way, but I'm not sure.
     
  32. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    A cursory test would indicate it definitely does want Id's to be shared between them since that's how it determines which ports are able to be utilized or connected or something. Doesn't even render ports if I return a cached GUID as the Id :)
     
  33. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Ya definitely don't do it that way. What about just creating a new GUID field in a new base node class?
     
  34. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    Yeah, that's what I did, it was mainly a curiosity.
     
  35. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    Where is that save data caching being done? I'm going to have to risk the data loss, or detect scene changes and do a save at that time. The delay caused by the save is a bit too intense for our usage.

    [edit] Found it

    Code (CSharp):
    1.         private void OnLostFocus ()
    2.         { // Save any changes made while focussing this window
    3.             // Will also save before possible assembly reload, scene switch, etc. because these require focussing of a different window
    4.             canvasCache.SaveCache();
    5.         }
    I'll have to dig into the NormalReInit() when gaining focus and see how much of that is critical. I assume it's just reloading the canvas at that point?

    I guess assembly reload is the big issue I have to worry about. The problem I have at the moment is that we have to jump in/out of the editor window quite a bit with out usage.


    [Edit again]
    So my plan is to use the OnBeforeAssemblyReload and OnAfterAssemblyReload editor window events to handle assembly reload as it's been done so far. Then the only other concern is what exactly is happening in NormalReInit() since that gets into validation of the canvasCache which I have no clue about yet. I'll likely do something similar for handling scene changes. At least have it interrupt scene load somehow and ask if you want to save.

    As said before, I commend you for being so diligent in helping we plebs utilize the system you folks built. You deserve some sort of reward. At some point here I'm gonna have to shoot you some $$ or something on paypal, at least enough to buy some drinks.. or a burrito, or something. ;)

    [Edit again AGAIN]
    Can I assume that canvasCache.nodeCanvas is the last loaded canvas, and that Validate on NodeCanvas is really only going to be an essential call if you monkeyed around with data in nodes or the canvas externally somehow?
     
    Last edited: Jun 6, 2018
  36. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    NormalReInit is just reinitiating the framework, including refetching types with reflection and stuff. Usually not resource intensive. It usually does not even load the canvas, unless of course it has been unloaded due to external influence, which this is all about (scene change, etc).
    Ya in some way you can now manually handle these cases, but afaik scene change can still not be detected by a callback, which is really a bummer.
    Finally, yes validate does nothing special, just checks data integrity and stuff. Not really a concern, will work without it but has helped me while developing several systems in the past.

    Thanks for your kind words, really appreciated:) Will do anything I can, since I do know the framework it's really not a big deal, doesn't take too much time assisting you:)
    Seneral
     
  37. BeautifulRiver

    BeautifulRiver

    Joined:
    Sep 19, 2016
    Posts:
    47
    Hi @Seneral, I downloaded the zip file from your Github and open the project in Unity 2018.1.1f1. Everything seems OK, but when I load the Calculation Cnavas and Graph Canvas assets in the Node Editor, it failed with the following exception:

    UnityException: Cannot load NodeCanvas: The file at the specified path 'Assets\Node_Editor\Resources\Saves\Calculation Canvas.asset' is no valid save file as it does not contain a NodeCanvas!

    Do you know why? Thanks for your time.
     
  38. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    So you downloaded the latest dev branch? Hm, weird then.
    When you click on these save files in the project window, do you get the canvas inspector shown? If not the file is probably corrupted by some versioning stuff. Will have to test explicitly in 2018.1.1 then.
     
    BeautifulRiver likes this.
  39. BeautifulRiver

    BeautifulRiver

    Joined:
    Sep 19, 2016
    Posts:
    47
    @Seneral Thanks for the reply. When I click on the save files. There is an error in the inspector: Script Missing (Mono Script).

    So it may be just a broken reference. I tried to assign a script into the slot, but the inspector is gray out. I can't do that with any script.
     
  40. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Hm that is weird. The SO scripts aswell as the save files should have their meta files included in the project, so no reference should be lost. The only other reason is compile errors. Do you have any compile errors in the project? Or did you do anything weird when importing, like copying from another project, duplicating, etc?
     
    BeautifulRiver likes this.
  41. BeautifulRiver

    BeautifulRiver

    Joined:
    Sep 19, 2016
    Posts:
    47
    Thanks for the suggestions! I just did a reimport all. Now I can open the save files in the node editor! It seems something was corrupted in my original project.

    Thanks for the excellent project!
     
  42. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Ah, glad it works now:) Probably really just some anomaly with the unity importer...
     
  43. Tarik_Boukhalfi

    Tarik_Boukhalfi

    Joined:
    Jul 9, 2012
    Posts:
    7
    Hello!

    I'm trying to figure-out how to use NodeEditoFramework in-game like in the WebGL demo. Any help is highly appreciated.

    Thanks,

    Tarik
     
    Last edited: Jun 13, 2018
  44. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Well, the WebGL demo is really just the github version imported in a project, with a single scene with a single game object with the RTNodeEditor script on it. It has a OnGUI function and calls into the framework to make it do the work. You can start from there to integrate it into your own scripts and stuff:)
    Oh forgot, since it is WebGL you can't load any actual files, so I also saved all the example canvases into the scene itself so you can load it there. Shouldn't matter to you though if you make a normal game, you have plenty of options on where to store your canvases (in actual game directory as XML, in unity resource folder as XML/ScriptableObject, in the scene as ScriptableObject, etc.)
     
  45. Tarik_Boukhalfi

    Tarik_Boukhalfi

    Joined:
    Jul 9, 2012
    Posts:
    7
    @Seneral Thank you Levin! I missed the Runtime Examples folder :)
     
  46. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    146
    @Seneral I does the editor maintain any state about whether the loaded canvas has had changes applied since load? Additionally, does it maintain any notion of unsaved changes? I assume not or it would be doing something with it already.

    If not and you were to add it, where would you go about it?
     
  47. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    No, you're right, nothing like that exists currently.
    I would assume such a notion would not include moving view (or even nodes), right?
    Not sure where I would start, probably whenever a callback is called. You could start in NodeEditorCallback to get reference to important changes, although that does not include NodeGroup creation and deletion yet...
    Ontop of that you would need to know about changes in the node GUI itself, which should be possible to implement in the node drawing routine with a GUI.changed check.
    If one were to implement this, you could ease the workload on the cache system a bit, so it won't save unnecessarily when just checking something and unfocussing the window (which will trigger a save as of now).
    Tell me if you need more info and are about to implement this:)
    Seneral
     
  48. KrytalityStudios

    KrytalityStudios

    Joined:
    Sep 12, 2016
    Posts:
    22
    Hi everyone! Hope all are doing well.

    I have been gone on a trip this previous week and will be this next week, but I just wanted to send an update of the way I want to do this.

    So once again, the database files, and the canvas files, will be two separate entities. I spent a little bit thinking about how to organize this, and I came up with this:

    Since I am using several canvas types, I am going to have a dedicated folder, somewhere in the editor folder, with the canvas save files in it. The database file can be saved anywhere, because pretty much all that seems to be needed is to basically create a new folder for the canvases as soon as a database is created, that has the databases ID for the name of the folder (either that or the databases name for the name of the folder). Then once that is done, the manager of these paths can keep up with the paths of both the canvases, and the database, so if things like the database's ID changes, the respective canvas folder can update the name as well. So therefore basically, to edit the database, in the inspector, you will click "Edit...", and then the database can open the editor, and supply it with the canvases to load, through the path manager which has references to those paths. Once that is done, if we have unsaved changes, I can bring up a dialog or something when the window is closed or unfocused or something like that, asking to save the changes, then if so, just save to the database using the interpreter. Hopefully that makes sense.

    So if you see any flaws or something, please report it to me. I haven't implemented this fully because of a bug right now with this little piece of code...
    Code (CSharp):
    1.            
    2. string[] foldersUnderResources = AssetDatabase.GetSubFolders(ResourceManager.GetDefaultResourcePath());  
    3. //just the basic resource folder for now because I don't have a specified folder yet
    4. //The problem is that this doesn't return any folders, and I know that this folder exists... Any help?
    5. //what I plan to do here is find all the subfolders under the resources folder, and if there is already one with a name that matches the database ID passed into this function, just return that path, but if there isn't one, create one and return the path to the newly created folder.
    6.  
    All help is greatly appreciated, cheers!
     
  49. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Cool, glad you got this all planned out. Sounds solid to me!
    Hm, maybe try with the actual System.File interface? Should definitely work...
     
  50. Seneral

    Seneral

    Joined:
    Jun 2, 2014
    Posts:
    1,206
    Hello everybody,
    I'll be on a trip to Japan from the 26.06. to the 19.07., so support / answers will be slower, and I'll have no development PC there.
    I'll try my best to respond asap!
    Seneral