Search Unity

NodeCanvas - (Behaviour Trees | State Machines | Dialogue Trees)

Discussion in 'Assets and Asset Store' started by nuverian, Feb 8, 2014.

  1. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    @nuverian
    Hi,
    I have two requests :
    1) I was trying to calculate some distance and store it in BB, but i don't see any math actions ?
    2) About AI, i would like to see the NavObstacle component available.
    I think i will create my own NodeCanvas action and condition nodes, but these two would have been a good addition.
     
  2. aidinz

    aidinz

    Joined:
    Apr 17, 2016
    Posts:
    63
    Thanks, I'm starting to like your product and also testing other similar packages, it's getting more clear that it's what we need! Hope this feeling lasts! :)

    1- I'm getting my head around it and I did have some progress. Your SubFSM is better than what we have previously in-house but with one difference. We could see the whole AI at one glance but from what I understand, I can see only the top view and can't see SubFSM's inside states and would require you to go in them, right?

    But yours is better suited for more complex states which ours was not limited but was very hard to work with after two level.

    2- I'm trying to add my own "Wander" state but reading the docs, I wondered if it should be a task, rather than a whole state. Am I right? Would you please describe the difference of each case please?

    3- I want to make have a lot small tasks/actions/not-sure-what-you-call-them to "modulize" some small behaviours like making a sprite component blink for a couple seconds, should I make them as actions or tasks?

    4- My custom state does not have an action list in the editor as your default ones does. What am I missing?

    5- How to pass parameters BBParameters to my custom states? Can it be more than one? Can it be random range of two float values?

    6- In PlayMaker, you can stack tasks on top of each other and I think we can do here as well but I'm not sure how to pass parameter to all of them. For example one state requires 5 parameters for 5 different tasks, how to pass all of them?
     
  3. KIR99

    KIR99

    Joined:
    Feb 21, 2017
    Posts:
    19
    Hey there,

    I think I ran into a small issue regarding NodeCanvas ( which might just be my behaviour trees)

    Sometimes when I run a project and start the scene, it crashes on play. I'm not entirely sure why since there's nothing in the console but it fixes itself when I remove all of my behaviours from the scene and within my shared assets folder to then re-import my behaviours. Perhaps my behaviours aren't built in a stable way where each spawnable NPC, searches the player with a tag and theres a fair bit of them being spawned on start but usually its fine.

    I know this is a wierd issue, if theres anyone who had a simular issue and fixed it please let me know it'll be much appreciated.

    Thanks :p

    EDIT: I think this issue occurs when my NPC's are left in the scene for too long or the prefabs themselves could be corrupted.
     
    Last edited: May 10, 2017
  4. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello and sorry for the late reply!
    Thank you very much for such a positive feedback! I really appreciate and I am so glad you enjoy NodeCanvas!
    I am also glad that someone found the ability to set SubTrees via variables useful! :)

    Please let me address your suggestions/questions.

    Aesthetic field attributes for overriding the names of Action fields in the editor
    You can use [Name(string)] above any field to alter it's name similar to how it's done for the type itself. Is this what you mean?

    Action field attribute for providing a tooltip
    Already planned and probably there in the next version :)

    Option to turn off comment wrapping / cause comments to widen nodes
    Can you please clarify what you mean with this one?

    The ability to drag FSM condition labels along the curve to position them when the algorithm wants to put to labels on-top of each other.
    There has previously been a similar (probably same) idea on the table, where the FSM condition label could manually be offset from where it should have been. This is a bit tricky to get right UI-wise, but I definitely can see the need for that or something similar.

    About the Blackboard Assets that is also something planned.
    The idea that I've been tinkering with, is the ability to optionally "append" an Asset Blackboard to the existing Blackboard component. As such the two blackboard would somehow combine in one set of variables that the graph is able to use the same way. Let me know if this is close to what you suggest?

    Really, thanks again for such a positive feedback!
    If you have any more suggestion, by all means do let me know!


    Hey,

    Sorry for late reply.
    1) Math or Vector functions, can be called by using the "Script Control / Execute Static Function" task. This action task basically exposes all existing functions of Unity (or other existing API) via reflection. Once the task is added you can select the function to call by clicking the "Select Static Method". Bellow for example Vector3.Distance is used.
    ExecuteStaticFunction.png

    2) Do you mean NavMeshObstacle being available as a type for variables for example, or something different? If so, you can add the NavMeshObstacle type, or any other type to be recognized by NC editor, simply by adding that type in the "Tools/NodeCanvas/Preferred Types Editor" window.

    Please let me know if that is what you mean.
    Thanks!

    Hey,

    Thanks! I am glad you like NC :)
    Let me address your questions:

    1) Yes, each SubFSM is viewed once you go inside the SubFSM node. The SubFSM nodes can't be seen altogether within the parent FSM. :)

    2) I'd personally suggest avoid creating custom states, but rather only create custom ActionTasks, which in turn are assigned to the existing ActionState. The benefit of working with Tasks, is that they are modular in the sense that you can potentially also use all created Tasks in BehaviourTrees (or even Dialogue Trees) as well if you chose to use them in the future.
    Action Tasks similar to a state also have callbacks for when the action starts, updates and finish (OnExecute, OnUpdate, OnStop), thus it is entirely possible to model a state only through creating ActionTasks and assigning them to the existin ActionState.

    3) Like above, for modularity you should use ActionTasks :)

    4) Custom States Nodes do not all come automatically along with an Action List, since a state node may not require an action list. Generally speaking, if you are creating a custom state node you don't really need an action list, since these are two contradictory ways of modeling a state. Once again, I would totally recommend to only use ActionTasks.
    Creating a custom state node, would normally only be necessary if you want to create a special case node for the FSM system as a whole, like for example the Concurrent State, or Any State nodes are. Some node that defines the structure of the FSM, not what it does (this should be up to ActionTasks once again :).

    5) If you still decide to use custom states, you can use BBParameters in a similar manner that is done in Task as well, by declaring a field like 'BBParameter<float> number;' for example. Doing so will allow you to link this parameter to a blackboard variable.

    6) Can you please clarify this question?

    Let me know.
    Thanks!

    Hello,
    Do you by any chance have made a circular SubTree reference? For example having a SubTree "A" within another SubTree "B", which in turn has another SubTree "A" within? :)
     
    KIR99 likes this.
  5. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    I didn't know it was available otherwise i would create my own node. Thanks.
     
    nuverian likes this.
  6. KIR99

    KIR99

    Joined:
    Feb 21, 2017
    Posts:
    19
    Hey i found what was causing the crash in my behaviours,

    I think i called a function on the player that was within another system (via gloabal BB) but it's all fixed now :)
     
    nuverian likes this.
  7. rcmkc

    rcmkc

    Joined:
    Jul 1, 2013
    Posts:
    5
    Hi guys! First of all, this is an awesome tool, thanks!

    I have one little trouble so far:

    One of my Condition Tasks in FSM takes some time to fill up (delayed sensor noticing). And while it progresses I need to prevent current Action State from executing assigned actions since some of them will break the noticing behavior (i.e. it will turn character's sensor the other way while it's still "noticing" something). All progress happens in task's OnCheck method, so pausing current behavior will effectively stop that too. While I might come up with something using coroutines or so, maybe there's some intended methods for achieving such thing that I missed?

    Thanks in advance!
     
    nuverian likes this.
  8. chasepettit

    chasepettit

    Joined:
    Oct 23, 2012
    Posts:
    42
    Just wanted to say thanks for creating such a great tool.

    Like most programmers probably do, I always insisted on rolling my own simple FSM system with generics, and it served me well in most situations. However, it started to become a bit of a maintainability nightmare in larger systems - adding/modifying states would at times require a nonsensical amount of work. In some situations, a visual node based system is almost a necessity if you want to be able to iterate quickly and easily.

    I considered maybe trying out PlayMaker, but it always seemed like overkill and a bit too "opinionated" on how games and classes should be structured, breaking a lot of pretty common sense tenants of OOP.

    I eventually tried out NodeCanvas, and it has really solved all of my maintainability issues for me and allowed me to just focus on the actual meat of the FSM. The custom tasks and blackboard system also made it incredibly easy for me to move all of the functionality of my old FSM states into NodeCanvas without impacting the majority of my game's code or requiring any sort of significant change to the game/code architecture.
     
    Last edited: May 12, 2017
    nuverian and zenGarden like this.
  9. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Thanks! I am really glad you like NodeCanvas.
    Hm. If I understand correctly you want to continue execute the condition OnCheck, but halt the current state actions. If so, that is unfortunately not really possible in an "official" way, because the condition OnCheck is actually updated from the current state update, which is also responsible for the actions update that it has. (Transition conditions are checked first then actions are updated.)
    I can't really think of a good way to handle this case. Have you tried maybe moving the stuff that you are doing from the condition, into an action of the state and have a condition respond to that instead through variables for example?
    If you do this, your could set the action list to "Run In Sequence" and put your action first. As such the rest of the actions bellow in the list will only continue after that action is finished (EndAction). Just some ideas to maybe help. Not really ideal though.

    Let me know what you think.
    Thanks!

    Hello!
    Thank you very much for such a positive feedback! I really appreciate it :)
    I am very glad NodeCanvas fits your needs and to hear that it was not a big rush to add it in an existing project!
    If you have any suggestions that you deem might make this even smoother (or any other suggestion for that mater), by all means do let me know.
    Thanks again!
     
  10. ldlework

    ldlework

    Joined:
    Jan 22, 2014
    Posts:
    46
    Would it be possible to allow BB variable binds to private properties and fields? This would allow me to have graphs access and manage internal game object component data/behavior while maintaining a separate public interface for other external game objects to utilize. By only supporting pubilic fields and properties I must pollute my component API with access that's only relevant to the graphs.
     
  11. ldlework

    ldlework

    Joined:
    Jan 22, 2014
    Posts:
    46
    Another thing I've been sort of desiring while using NodeCanvas is the ability to respond to events outside of the central state-flow of my graphs:
    upload_2017-5-18_0-14-1.png
    It would be super neat if I could have a separate node here, sort of like a continuous node, that waited for an event to fire. Anytime it did, it would either execution actions on the node, or it would execute a sub-graph (without disturbing the main graph). The example I'm thinking of is, when my Attacked component receives a "you've been attacked with X damage" event, this node would be able to do something to a BB variable without having to change state, etc.
     
    BigToe likes this.
  12. BigToe

    BigToe

    Joined:
    Nov 1, 2010
    Posts:
    208
    I'm totally in agreement here.
     
  13. strich

    strich

    Joined:
    Aug 14, 2012
    Posts:
    374
    Is it possible to do a stack-based FSM in nodecanvas?
     
  14. chasepettit

    chasepettit

    Joined:
    Oct 23, 2012
    Posts:
    42
    I don't think it's explicitly supported, but it seems like it would be pretty trivial to implement something like that.

    Without putting too much thought into it, I'd say you'd probably just put a stack<string> in your BB variables. You'd push/pop from that stack and then funnel everything into a main state that sends an event based on whatever is on the top of the stack, that event would then trigger the corresponding state.
     
    nuverian likes this.
  15. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Technically allowing variables to bind to non-public properties and fields is trivial, but it is something I would definitely like to avoid since it is I think a bad practice to allow that. First of all it will fill the list with countless of properties/fields, but most importantly it will show private properties and fields that are really not meant to be modified outside of the class and thus the reason they are not public in the first place :)
    Why not just make the properties you want to be able to be bound public, since they are properties meant to be modified externally anyway?

    Are we referring to something like the existing "Concurrent" node but instead of only having a list of action, it also have a prequisite condition that needs to be met before executing the actions?
    If so, I could add a condition prequisite to the Concurrent node pretty easily :)
    Concurrent.png

    You can of course have as many of them as you like and all will run in parallel.
    Let me know what you think.

    While not stack-based at it's core, I am already looking at implementing some stack-based features that makes sense with the current FSM implementation in NodeCanvas.
    One of them is the ability to automatically return to the previous state the FSM had active once a state that has been triggered from the "Any State" node has finished.
    Stacked.gif

    Suggestions are welcome of course.
     
  16. ldlework

    ldlework

    Joined:
    Jan 22, 2014
    Posts:
    46
    Conditional concurrents would be perfect!

    BTW, I ran into an issue where I discovered I could bind the BB variables to my component's signals - but obviously that wouldn't do anything interesting. So I wrote some code that goes through all off the BB variables, determines if the `varType` is of ISignal<>, then I generate a lambda that calls the correct `SendEvent<>` and add that as a listener to the bound signal. The result is that I can respond to the various events of my components by way of graph events. Its crazy convenient. If you think this would be an interesting feature for the asset let me know. People could use your signals, or any signal that uses the right interface and binding a BB var to it will cause it to be raised as a graph event.
     
  17. strich

    strich

    Joined:
    Aug 14, 2012
    Posts:
    374
    Honestly? You should do it properly. The graph should show clearly the stack, and the stack needs to be an actual stack, not just the last state.
     
  18. emreCanbazoglu

    emreCanbazoglu

    Joined:
    Jan 31, 2012
    Posts:
    15
    Hello There,

    It's me again :)
    I think there is a bug with the nested prefabs. Lets say I have a prefab hierarchy like this:

    A
    ---B(with behavior tree)

    If I delete the child object (B), in the prefab shown in the project, the bounded behavior tree to B won't be deleted when the prefab is applied.

    Thanks!
    Emre
     
  19. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    825
    Hello,

    Is the documentation on creating custom FSM states out of date? I am referring to this page: http://nodecanvas.paradoxnotion.com/documentation/?section=creating-custom-fsm-nodes

    I ask because the script shown doesn't work. Basically none of the methods shown appear to exist on the FSMState class.

    Furthermore the property decoration used in the example for Category and Icon don't seem to exist. Basically none of what in that example appears to work :)
     
  20. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,

    Conditional Concurrent will be there in the next version then. I've already implemented it and works quite well indeed. :)

    About the Signal binding you mention, I am not exactly sure what you mean since I don't really know what your ISignal<> interface really is, but by all means please do send me the code if you want so that I can better understand what you mean to support_AT_paradoxnotion.com or simply start a new thread at the forums for discussion :)

    Thanks!


    Maybe. I will think about it for the future and if is something that can be done without introducing "breaking changes" (keeping backwards compatibility in all cases) then certainly I will.
    Thanks.

    Hey :)
    Thanks for the report!
    I will check this out immediately.

    Hello,
    I have updated the documentation to the latest API and added the namespaces required. Sorry for the inconvenience and thanks for leaving a "Suggest Edit" by the way!
     
  21. yotingo

    yotingo

    Joined:
    Jul 10, 2013
    Posts:
    44
    I have a few quick questions.

    1. How do I start a bound graph from script?

    I don't want the Behavior Tree to start until I have called it, then I only want it to run once. The Behavior Tree is choosing which of multiple Dialogue Trees to show based on a Priority Selector. I tried using various forms of StartGraph() but can't find the right syntax.

    2. Using NodeCanvas, how do I resume a paused Slate cut-scene?

    3. How do I SendMessage to a C# script on the same object as my BehaviourTree or DialogueTree?

    SendMessage with NodeCanvas doesn't seem to be working the same way as it does in Slate.



    Thanks for your help!

    Edit: I had another question about input but figured it out. I'd still like to know how to start a Graph with C# and resume a cut-scene though. :D
     
    Last edited: May 26, 2017
  22. ldlework

    ldlework

    Joined:
    Jan 22, 2014
    Posts:
    46
    Neat, this is going to be really powerful.

    I have been having an issue for a couple days and its starting to drive me insane. Everytime VisualDesignCafe's NestedPrefabs asset serializes stuff, some NodeCanvas graph has been corrupted and fails to deserialize or something. The error is not descriptive and I tried to use breakpoints to figure out what file is causing the issue but I couldn't!

    Do you have any ideas?

    Code (csharp):
    1.  
    2. <b>(Deserialization Error:)</b> System.Exception: Error while parsing: Bad Int64 format with 7b2276657273696f6e223a322e362c2274797065223a224e6f646543616e7661732e4265686176696f757254726565732e4265686176696f757254726565222c226e616d65223a224265686176696f757254726565222c226e6f646573223a5b5d2c22636f6e6e656374696f6e73223a5b5d2c226c6f63616c426c61636b626f617264223a7b225f6e616d65223a224c6f63616c20426c61636b626f617264222c225f7661726961626c6573223a7b7d7d2c226465726976656444617461223a7b22726570656174223a747275652c222474797065223a224e6f646543616e7661732e4265686176696f757254726565732e4265686176696f7572547265652b4465726976656453657269616c697a6174696f6e44617461227d7d; context = <696f6e44617461227d7d>
    3.   at ParadoxNotion.Serialization.FullSerializer.fsResult.AssertSuccess () [0x0000d] in D:\Documents\Unity\neon-jungle\Assets\Synced Assets\loaned\ParadoxNotion\NodeCanvas\Framework\_Commons\Runtime\Serialization\Full Serializer\fsResult.cs:147
    4.   at ParadoxNotion.Serialization.FullSerializer.fsJsonParser.Parse (System.String input) [0x0000c] in D:\Documents\Unity\neon-jungle\Assets\Synced Assets\loaned\ParadoxNotion\NodeCanvas\Framework\_Commons\Runtime\Serialization\Full Serializer\fsJsonParser.cs:495
    5.   at ParadoxNotion.Serialization.JSONSerializer.Deserialize (System.Type type, System.String serializedState, System.Collections.Generic.List`1 objectReferences, System.Object deserialized) [0x00065] in D:\Documents\Unity\neon-jungle\Assets\Synced Assets\loaned\ParadoxNotion\NodeCanvas\Framework\_Commons\Runtime\Serialization\JSONSerializer.cs:88
    6.   at ParadoxNotion.Serialization.JSONSerializer.Deserialize[GraphSerializationData] (System.String serializedState, System.Collections.Generic.List`1 objectReferences, NodeCanvas.Framework.Internal.GraphSerializationData deserialized) [0x00013] in D:\Documents\Unity\neon-jungle\Assets\Synced Assets\loaned\ParadoxNotion\NodeCanvas\Framework\_Commons\Runtime\Serialization\JSONSerializer.cs:67
    7.   at NodeCanvas.Framework.Graph.Deserialize (System.String serializedGraph, Boolean validate, System.Collections.Generic.List`1 objectReferences) [0x00028] in D:\Documents\Unity\neon-jungle\Assets\Synced Assets\loaned\ParadoxNotion\NodeCanvas\Framework\Runtime\Graphs\Graph.cs:132
    8. UnityEngine.Debug:LogError(Object, Object)
    9. NodeCanvas.Framework.Graph:Deserialize(String, Boolean, List`1) (at Assets/Synced Assets/loaned/ParadoxNotion/NodeCanvas/Framework/Runtime/Graphs/Graph.cs:145)
    10. NodeCanvas.Framework.Graph:Deserialize() (at Assets/Synced Assets/loaned/ParadoxNotion/NodeCanvas/Framework/Runtime/Graphs/Graph.cs:77)
    11. NodeCanvas.Framework.Graph:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize() (at Assets/Synced Assets/loaned/ParadoxNotion/NodeCanvas/Framework/Runtime/Graphs/Graph.cs:47)
    12. UnityEditor.AssetDatabase:LoadAssetAtPath(String, Type)
    13. VisualDesignCafe.Editor.Prefabs.NestedPrefabPostprocessor:RefreshPrefabInDatabase(String)
    14. VisualDesignCafe.Editor.Prefabs.NestedPrefabPostprocessor:EnsurePrefabDatabaseIsValid()
    15. VisualDesignCafe.Editor.Prefabs.NestedPrefabPostprocessor:EditorUpdate()
    16. UnityEditor.EditorApplication:Internal_CallUpdateFunctions()
    17.  
     
  23. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087

    Hey,
    Sorry for the late reply!
    Please let me address your questions:


    1) To avoid a BehaviourTree automatically starting, you can set the "OnEnable" setting in the BehaviourTreeOwner inspector to "Do Nothing".
    Then, from within one of your scripts, you simply need to call something like this:
    Code (CSharp):
    1. GetComponent<BehaviourTreeOwner>().StartBehaviour();
    If you want the behaviour tree to only run once each time StartBehaviour() is called as explained above, then you need to disable the "Repeat" option once again found in the BehaviourTreeOwner inspector.

    2) If you are using the NodeCanvas - Slate integration package from the downloads section of either of the two asset websites, you can use the "PlayCutscene" action task even to resume a cutscene. This works because if a cutscene is paused and Play is called for it, it will be resumed instead of starting over.
    If you are not using the integration package, you can still use NodeCanvas "Script Control/Execute Function" task, to call the "Resume()" function on the cutscene through reflection, as well of course as any other function available. :)

    3) You can use the "Script Control/Common/Send Message" action task to do exactly that.
    Can you please clarify what you mean that it does not work the same as in Unity? The action is using the exact same SendMessage unity function :)

    Let me know.
    Thanks!


    Hey,
    Is it possible for you to please send me the graphs that throw this deserialization error so that I can check out what exactly is going on wrong here? (support_AT_paradoxnotion.com).
    That would be really great if you can.
    Thanks!
     
  24. RecursiveRuby

    RecursiveRuby

    Joined:
    Jun 5, 2013
    Posts:
    163
    Hey,

    So my question is a little bit complicated to explain so I'll try and give a bit of an example. So far a lot of my Tasks tend to contain more functionality than they should and aren't really cohesive in that regard. I know its bad design practice but I tend to reuse these tasks a lot so breaking up the functionality and creating all the would be individual tasks every time would be a bit of an annoyance.

    Let me give an example. So for my current project I have a task "Spawn Plane" which basically does
    • Gets a Random Position
    • Gets a Random Heading
    • Check if any planes are nearby. If so get a new random position and heading until no planes are nearby
    • Instantiate the plane prefab and set the position and rotation
    All of those points could be broken down into individual tasks. In fact thats what I'm doing at the moment. Due to how tightly coupled the logic is with a single Task doing all of the aforementioned, implementing some behavioral aspects can be difficult. The problem now really comes down to how much setup goes into something which is commonly repeated across many different behavior trees i.e. instead of having one task do one job we now have several doing several smaller jobs. Ultimately it leads to cleaner more flexible code. Which is good. Its just annoying if you get me.

    So what I initially thought was to create a SubTree called "SpawnPlane" this sub tree has the common setup for spawning a plane. Which can easily be reused and encapsulates the behavior nicely. If I ever needed to spawn planes under special circumstances and without using this set behavior, I can. Only the issues is to spawn a plane I need to specify the prefab of the plane on the "Spawn Plane" action. Since I'm using a SubTree I cannot so easily specify a prefab as I could before. Keep in mind my graph is also asset based so the blackboard doesn't seem to work very well until runtime. I could use a dynamic var which just saves a set prefab to a variable and then the SubTree could use that. That is just still a little annoying though. Since I can't just drag and drop the reference in from the editor straight into the sub tree.

    My current setup is for the Action Task that actually spawns the plane to use the agent as the prefab that should be instantiated. So I just decorate my SubTree with an Override Agent and specify the prefab from there. It works but again, it just has that small level of setup and is not quite as transparent as I would like.

    So finally my question comes down to this,
    • Is using an override agent like I mentioned to specify a prefab a good way of doing things?
    • Is there anyway a SubTree could expose a field which can be used like a drag and drop? (this would be ideal)
    • Or is there anyway we could get functionality to Save a list of actions to a common template which we can then create like an action. A macro so to speak I guess. Since I can add all the functionality I need to an Action List it just comes down to swapping out prefabs which is the issue. This is keeps all the logic isolated to one node which is nice.
    I guess the ultimate question is, is there anyway to pass references to a SubTree without means of a dynamic var or blackboard variable. Just the ability to pass a reference as I would with a action. If the SubTree task had an option to set the value of a dynamic var just before it was accessed this would be very useful. Since you could easily use SubTrees as if they were a single Action.

    Sorry for the big wall of text. I hope you kind of get what I'm trying to explain. I'm never good at explaining these things. I can provide images if needs be.

    Thanks In Advance!
     
  25. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello and sorry for the late reply.
    No problem at all about the big text :)
    I completely understand what you are saying and what you want to achieve.

    Generally speaking, I don't really find it bad at all to have a single action task do a lot of things, as far as, these things make up for a higher level action similar to how a normal code function would have been for your game, like for example 'Create Plane', 'Take Off' or 'Land'. Of course the more you break down that action into individual lower level ones, the more control you have, but also like you mention, the harder it gets to manage the tree, or re-create that same action out of these several lower level ones.

    So, my personal suggestion on this, is that when creating custom actions, it is preferable to be higher level ones, because it will lead to a much cleaner and more manageable tree design, with which it will also be easier to experiment with as well. Ideally, a behaviour tree should be used as a visual authoring tool of *when* higher level actions happen, rather than *how* they do. At least in my opinion :)

    There is a feature which I've worked on (but unfortunately is heavily delayed. Sorry @ chai! ), and that is the ability of SubTrees to have local blackboard variables, which variables are able to be mapped from the root tree's blackboard variables and as such each subtree can essentially have parameters, in a similar fashion to how an action task does now.

    Unfortunately though, this feature is heavily delayed (but not dropped), due to keeping projects backwards compatible.
    If I am not mistaken, is this what you ideally would like to be able to do?

    Let me know what you think.
    Thanks!
     
    TeagansDad likes this.
  26. RecursiveRuby

    RecursiveRuby

    Joined:
    Jun 5, 2013
    Posts:
    163
    Hey, Thanks for your reply :)

    and yes being able to set parameters like that directly in the sub tree would be exactly what I had in mind. I have created actions that do more than one task quite a lot in the past and they've been perfectly fine. Only now in this instance I need to break up some logic depending on the level. So having this one action doing everything is not ideal.

    Its not something thats majorly halting me in my tracks, since I could just create several actions which do similar things and are more or less coupled to performing specific tasks. I just much prefer the idea of using SubTrees in the way that you described above. Since it keeps the code clean and keeps the Tree design clean.
     
  27. Kobix

    Kobix

    Joined:
    Jan 23, 2014
    Posts:
    146
    I still crave DAG for Behavior Tree :(

    Any easy 'boolean' fix? Or how can I do it myself?
     
  28. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Hello. In FSM, is there a way to represent a true/false branch with checking the condition only once? Currently I do it this way, but it seems silly:

    score.PNG


    Here is what I would like to do:
    flow.PNG
     
  29. Shadeless

    Shadeless

    Joined:
    Jul 22, 2013
    Posts:
    136
    @username132323232
    For stuff like that you should use a Behavior Tree. You can even use it in an FSM by making a Sub Tree.
    For your specific case. You can use the Binary Selector Composite which does exactly what you want.

    Cheers
     
    nuverian likes this.
  30. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Thank you for the idea. I've been using NodeCanvas for some time now, but only the FSM part. So for each true/false check you suggest adding a Sub Tree inside the FSM? I'm sure that would work, but it seem even more complicated than what I'm doing now. Shouldn't there be an easier way?
     
  31. Shadeless

    Shadeless

    Joined:
    Jul 22, 2013
    Posts:
    136
    Yeah, the way you're doing it already :D
    It's not complicated at all by the way. In fact I don't have an FSM right now without a SubFsm or SubTree.
     
  32. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Thanks for the follow up.
    I think I will need to put more pressure in this feature as it is probably and currently the most requested one, and finally release it as soon as possible. :)


    Hello,
    Behaviour Trees by design are really not Directed Graphs and of course work quite differently.
    One thing you can do, is to open up BTNode.cs and change maxInConnections from 1, to -1. This will allow nodes to have multiple parents. Doing this though, is neither really meant to be done, nor supported :)
    Can you please describe what you want to do, or how you envision a combination of these would be?
    Thanks.


    Hello,

    Just like @Shadeless said (Thanks!), what you want to achieve and the image your posted, is really what a Behaviour Tree is (and an FSM is not :) ) An FSM, should best be used when each node actually represents a State. In the image you posted, Check Score for example, does not really represent a State. On the other hand, the Binary Selector in the BehaviourTree system specifically, is exactly what is represented in the image.
    BinarySelector.png

    With that said, I have quickly made a new custom node for you to be able to do the same thing even in the context of an FSM system. It's not extensively tested, but it should work fine.
    Branch.png

    Following is the code of the new Branch custom node. Please save it outside of the NodeCanvas folder since at least for the the time being I do not plan to include this officially. :)
    Code (CSharp):
    1. using UnityEngine;
    2. using NodeCanvas.Framework;
    3.  
    4. namespace NodeCanvas.StateMachines{
    5.  
    6.     public class Branch : FSMState, ITaskAssignable<ConditionTask> {
    7.  
    8.         [SerializeField]
    9.         private ConditionTask _condition;
    10.  
    11.         private ConditionTask condition{
    12.             get {return _condition;}
    13.             set {_condition = value;}
    14.         }
    15.  
    16.         Task ITaskAssignable.task{
    17.             get {return condition;}
    18.             set {condition = (ConditionTask)value;}
    19.         }
    20.  
    21.         public override bool allowAsPrime{ get {return false;} }
    22.         public override int maxInConnections{ get{return -1;} }
    23.         public override int maxOutConnections{ get{return 2;} }          
    24.  
    25.         protected override void OnEnter(){
    26.             if (condition == null){
    27.                 Finish(false);
    28.                 return;
    29.             }
    30.  
    31.             var i = condition.CheckCondition(graphAgent, graphBlackboard)? 0 : 1;
    32.             (outConnections[i] as FSMConnection).PerformTransition();
    33.             Finish( i == 0 );
    34.         }
    35.  
    36.  
    37.         ////////////////////////////////////////
    38.         ///////////GUI AND EDITOR STUFF/////////
    39.         ////////////////////////////////////////
    40.         #if UNITY_EDITOR
    41.  
    42.         public override string GetConnectionInfo(int i){
    43.             return i == 0? "TRUE" : "FALSE";
    44.         }
    45.  
    46.         #endif
    47.  
    48.     }
    49. }

    Let me know what you think.
    Thanks.


    Thanks for the help :)
     
  33. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Wow! I didn't expect a custom-made node. Thanks a lot! It seems to work fine.

    Also, thank you for explaining why Branch node was not included in FSM (not really a State). In NodeCanvas, could FSM be considered a subset of Behaviour Tree? I'm thinking of converting my FSM into a Behaviour Tree since it sounds that this is what I actually need :)
     
  34. strich

    strich

    Joined:
    Aug 14, 2012
    Posts:
    374
    Can we expect an update that resolves the 8 or so warnings in the 2017.1 beta branch? A bunch of Unity calls are now marked as obsolete.
     
  35. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey, You are very welcome!
    You can have FSMs nested in a BehaviourTree, yes, even though it makes much more sense to have them the other way around, meaning having nested BTs in an FSM. :)

    Yes, an update for Unity 2017 will of course be made, within a few days before it's release since because it's beta, more things may change.
    Thanks.
     
  36. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Sorry, I guess my question was not clear. I was asking if it's easy to convert an FSM into a BT. So far I have been using NodeCanvas only for FSMs. My FSM has about 30 nodes and I'm curious if it's worth it or even possible to convert it into a BT :)

    Also, since you mentioned nested FSMs and BTs, is there any performance hit due to nesting? How about several levels of nesting (FSM inside BT inside FSM, etc.)?
     
  37. jingray

    jingray

    Joined:
    Feb 6, 2015
    Posts:
    53
    Nodecanvas not working on system pooling ?!
    While game object set active : false. Nodecanvas doesn’t not restart behavior tree owner if I use decorate Filter 1 time.
    How to restart all state node in behavior tree owner ?!
    Please help. Thanks
     
  38. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Wow, I totally missed your post. I am so sorry!
    It's not really easy to "convert" or transfer from one system to the other, since they work very much differently and require a quite different design approach. Automatic conversion is definitely not an option for that same reason if that is what you ask :) The good thing with NodeCanvas though, is that if you have any custom actions or conditions created, you can effortlessly re-use them in both systems :)

    Regarding your second question, there is a small performance hit when using nesting graphs, which takes presence though, only when the nested graph is initialized (thus only once). Other than that, is shouldn't matter how many levels deep the nested graph go.

    Cheers!

    Hello,

    I have replied to your same question on the NodeCanvas forums. Please let me know there so that we keep the discussion easier to follow.
    Thanks.
     
  39. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Thanks! That clarifies the situation for me. I will probably keep FSM for my current project, but will try BT next time. It's great to know that there's no real performance hit caused by nesting. I said it before and will say it again: NodeCanvas rocks!
     
  40. jingray

    jingray

    Joined:
    Feb 6, 2015
    Posts:
    53
    Yes. It's working.
    Team "Nodecanvas" support very good.
    Thanks.
    -Like
     
  41. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    You are very welcome and thanks a lot for your positive feedback once again!
    I really appreciate it!

    I am very glad the solution worked for you!
    Thank you!
     
  42. BSECaleb

    BSECaleb

    Joined:
    Jan 29, 2009
    Posts:
    72
    I'm having trouble setting up a Condition Task to subscribe to a c sharp event in a FSM. When I select "Check CSharp Event<Object>" all scripts attached to the game object are grayed out so I'm unable to select my event.
    This is the event signature in the class (derived from MonoBehaviour):

    public event System.Action<ConsumableItem> OnItemSelected;

    If I create a "test" event in the same MonoBehaviour it shows up:
    public event System.Action<float> OnFloatTest;

    ConsumableItem is derived from ScriptableObject up the chain. Does the event type parameter have to be a literal Object? Is there a way to subscribe to events with custom types? I only need the notification to trigger a state change but I use the same event in other parts of the code...
     
  43. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,

    Due to how events work and them being quite strict, you will need to please select and use the CheckCSharpEvent version with the generic argument being the same type as your event generic argument, thus in this case, "Check CSharp Event<ConsumableItem>".

    To make that version show up in the dropdown menu when selecting an Action Task, you will just need to add your type "ConsumableItem" in the PreferredTypes Editor list, so that NodeCanvas knows that it's a type you want to work with.

    Please let me know if that works for you, or if you need any clarification on the above.
    Thanks!
     
  44. BSECaleb

    BSECaleb

    Joined:
    Jan 29, 2009
    Posts:
    72
    That did the trick! I forgot all about the PreferredTypes Editor.
     
  45. Member123456

    Member123456

    Joined:
    Oct 17, 2012
    Posts:
    237
    Are their any known issues with Unity 2017 currently? Looking to upgrade since its been officially released now, but Node Canvas is life...
     
  46. BSECaleb

    BSECaleb

    Joined:
    Jan 29, 2009
    Posts:
    72
    I'm using 2017.1.0b5 and it does throw warnings but works fine. Not sure about the new release or if there is a nodeCanvas update yet.
     
  47. Filipinjo

    Filipinjo

    Joined:
    Jan 7, 2014
    Posts:
    22
    Hey there... I'm so sorry to bother you but I get this error most of the times:

    There is a duplicate <b>GlobalBlackboard</b> named '_BaseController_BB' in the scene. Please rename it.
    UnityEngine.Debug:LogError(Object, Object)
    NodeCanvas.Framework.GlobalBlackboard:Awake() (at Assets/3rdParty/ParadoxNotion/NodeCanvas/Framework/Runtime/Variables/GlobalBlackboard.cs:75)

    I'm pretty sure that I have only one object with global _BaseController_BB in the scene... I do have it saved as a prefab could these things be related? Does anyone have a clue how I could solve this? :D

    Tnx in advance.
     
  48. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey guys,

    The current NC version works with Unity 2017 and the warning are harmless and easy to fix, but still very annoying to exist in any case.
    A new version of NodeCanvas will be send to the asset store with proper support for Unity 2017 very soon!

    Thanks a lot! :)

    Hello,

    There used to be a problem with prefab GlobalBlackboards like the one you describe on previous versions, but should be fixed in last version currently online. Are you using the last NodeCanvas version 2.6.3?

    Please let me know.
    Thanks in advance!
     
  49. Filipinjo

    Filipinjo

    Joined:
    Jan 7, 2014
    Posts:
    22
    Hey there,

    I'm sure I had it updated... But to be 100% sure I deleted the package, checked if the update is available and reimported it... The problem keeps appearing, usually when I try to build and run the game.

    Looking forward for your answer,

    Regards
     
  50. Filipinjo

    Filipinjo

    Joined:
    Jan 7, 2014
    Posts:
    22
    Any other ideas? :/