Search Unity

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

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

  1. nuverian

    nuverian

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

    Sorry for late reply.
    I was able to replicate this. Thanks.

    To quickly fix this please open up ConditionList.cs and comment out lines #78-79.

    Let me know if this works for you.
    Cheers!
     
  2. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    Works great, Nuverian. Thanks!
     
  3. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    Hi,

    Using NodeCanvas with Unity 5.1.1f1 still have the following yellow warnings:

    Assets/NodeCanvas/Framework/_ParadoxNotion (shared)/Design/PartialEditor/GenericInspectorWindow.cs(18,25): warning CS0618: `UnityEditor.EditorWindow.title' is obsolete: `Use titleContent instead (it supports setting a title icon as well).'

    Assets/NodeCanvas/Framework/Design/Editor/Windows/TaskWizardWindow.cs(23,25): warning CS0618: `UnityEditor.EditorWindow.title' is obsolete: `Use titleContent instead (it supports setting a title icon as well).'

    Can you fix them in the next version?
     
  4. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    I feel the need to point out that Nodecanvas 2 is awesome. I'm very reticent to rely on 3rd party tools for the core components of my games—the prospect that they might stop getting maintenance one day is too risky. However, Nodecanvas is my only exception. It's doing incredible things in my project, and I love how flexible it is. Don't ever get discouraged, nuverian. Your work is superb.
     
  5. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    @sanpats Are you using the last NC version? I fixed this in last update.

    @Marble Thanks a lot man! It's great to read such feedback and is really appreciated as well as encouraging by itself :)
    Thanks again!
     
  6. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    Yes, I bought NodeCanvas last week, in July. The latest version (2.3.6) on the Asset Store is from Jun 29th.
     
  7. nuverian

    nuverian

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

    I probably might have missed something. Yes. I will definetely fix it in next version.
    Also, thanks for getting NC :)
     
  8. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    It's a nice framework. :)
     
  9. Cheshire Cat

    Cheshire Cat

    Joined:
    Sep 18, 2012
    Posts:
    39
    Hi Nuverian,

    I am starting a new project and considering to start using NC. After reading a documentation thoroughly, I am a bit confused, so I need your help: I am gonna implement a pretty much complicated logic, including asynchronous requests to servers aka Google and Facebook, manage databases, send remote messages between users, perform voice recognition and so on.

    I intended to use NC just like another SDK for visual FSMs and behavioral trees - just like, let's say, Facebook SDK I use for social integration. But as far as I understand, Node Canvas MUST be a core of the whole architecture. Does it say I need to change my mind totally to start using it? I mean instead of writing C# functions which with if(), while() loops, hashmaps and all those old school stuff, I need to start implement all the functionality with new level of abstraction which NC provides - Graphs, Nodes, Tasks and Actions?

    I did read about Script Control Tasks - but it seems to provide very limited functionality - the function will return synchronously or will run as coroutine, but what about asynchronous request to Google servers?

    So my question is whether I can keep writing a most of the code as I used to - with classes, inheritances, functions, templates, dynamic datatypes and all that instruments C# provides, or I need to learn a whole new way of programming using Graphs, Nodes, Tasks and Actions?

    No criticism is intended here; I am just trying to understand whether NC is another Visual Scripting tool like PlayMaker, or it can be used just for providing some useful functionality, alongside other SDKs, without totally changing the way a developer is used to work.
     
    Last edited: Jul 20, 2015
  10. nuverian

    nuverian

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

    The goal of NC is really to be as less intrusive as possible to your way of working. It neither has to be the core of your design, nor you have to change your way of working, no :)
    You can write/design your code as normal and simply use NC as another component/SDK in your architecture to visualy "glue" that code together and run behaviours (BTs/FSMs) at a top-most level.

    The Script Control Tasks are mostly there as an easy way for non-coders to execute a lot of existing functionality. Coders will most probably write custom Tasks (actions/conditions) to interface with their code in case Script Control does not suffice.
    When it comes down to this, you are also free to write whatever code you like for when creating custom NC Tasks.

    The bottom line is that, graphs, nodes and tasks (Behaviour Trees and State Machines) are not there to visualy code a program, but rather to visualy organize a behaviour by preferably calling existing functionality already implemented in the usual ways.

    I hope I clarified some things, but if you need more details or have more questions, please let me know. :)
    Cheers!
     
  11. Cheshire Cat

    Cheshire Cat

    Joined:
    Sep 18, 2012
    Posts:
    39
    Nuverian,

    Thanks for the quick answer. If NC can be used as SDK, it's great news. But it still not clear for me how I can transform the existing code of FSM I have now into the NC. So let's take the trivial FSM and see how it can be written in terms of NC, if you don't mind.

    So let's say I have FSM class, which holds Start State, which is a class also, which calls InitializationManager class methods, get back Events from him, and based on Events rather calls its other methods or goes to Idle State. Then Idle State waits for user input, and if user pressed specific button, goes to FacebookConnection State, which calls FacebookManager class (asynchronous) methods, get back Events from it and then calls other manager methods or goes back to Idle.

    How that simple FSM can be implemented in NC? What is GraphOwner here, what is Graphs, Nodes, Actions and Tasks?

    Thanks for your help,
    Ilya
     
    Last edited: Jul 21, 2015
  12. nuverian

    nuverian

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

    The best way to think of this would be an analogy to Unity's Animator/Animator Controller.
    In regards to FSMs...
    • The GraphOwner is the equivalent of the Animator Component.
    • The Graph is the FSM, the equivalent of the Animator Controller.
    • Nodes are the States.
    • Action Tasks are what happens in States. You add ActionTasks in states.
    • Condition Tasks are how/when State Transitions take place. You add ConditionTasks in transitions.
    So for your example you would have and FSMOwner in some game object and create an FSM with three States along with the coresponding transitions between them.
    In your first (start) state you would create and add an Action Task, which on execution it will call the methods in InitializationManager and subscribe to some of it's events. In your transition between that first state and the "Idle" state you would have a ConditionTask to check for an FSM Event name, like for example "OnInitSuccess".
    When the coresponding InitializationManager event is raised, you would call FSM.SendEvent("OnInitSuccess") to make the transition to the Idle State (or simply call FSM.TriggerState("Idle")).
    Code (CSharp):
    1. public class Init : ActionTask{
    2.  
    3.     protected override void OnExecute(){
    4.         InitializationManager.OnSuccess += OnSuccess;
    5.         InitializationManager.Init();
    6.     }
    7.  
    8.     protected override void OnStop(){
    9.         InitializationManager.OnSuccess -= OnSuccess;
    10.     }
    11.  
    12.     void OnSuccess(){
    13.         SendEvent("OnInitSuccess");
    14.     }
    15. }

    The Idle state is similar. You would make a transition from Idle to FacebookConnection state, but this time you want the transition to happen when the user pressed a key. So you would create (or use the existing) ConditionTask that returns true when the user pressed a key.
    Code (CSharp):
    1. public class SpaceDown : ConditionTask{
    2.  
    3.     public KeyCode keyCode = KeyCode.Space;
    4.  
    5.     protected override bool OnCheck(){
    6.         return Input.GetKeyDown(keyCode);
    7.     }
    8. }

    The above is one way of doing this. I dont' know if you had something else in mind, but I hope this helped.

    Thanks.
     
  13. Cheshire Cat

    Cheshire Cat

    Joined:
    Sep 18, 2012
    Posts:
    39
    Nuverian,

    Thanks for the clarification, I think I start to understand the concept.

    Another question: As far as I can understand, it is possible to send Event with the only argument of type float. I've got a lot of code which uses Events with multiple arguments, which are stored in the System.Collections.Hashtable. How is that can be solved?
     
  14. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    If you are refering to the NodeCanvas events, you can send and check an NC Event of any type of argument like so:
    SendEvent<T>(string name, T value).
    If you are refering to the c# events, there is no limitation there.
    Code (CSharp):
    1. //Example
    2. public static class AStaticClass{
    3.     public static event System.Action<Vector3> SomeEvent;
    4. }
    5.  
    6. //Action Task
    7. public class MyAction : ActionTask{
    8.    
    9.     protected override void OnExecute(){
    10.         AStaticClass.SomeEvent += this.EventRaised;
    11.     }
    12.  
    13.     protected override void OnStop(){
    14.         AStaticClass.SomeEvent -= this.EventRaised;
    15.     }
    16.  
    17.     void EventRaised(Vector3 vector){
    18.         //send an NC graph event for a transition to take place
    19.         SendEvent<Vector3>("Finish", vector);
    20.     }
    21. }

    It's important to notice that NC Events and c# events are different :)

    Cheers!
     
  15. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    FSM transitions are supposed to evaluate in order, right? I have one FSM asset reference on two different Owners, yet they evaluate the same transition list differently.

    The attached screenshot shows what I mean. This is an FSM for a door. On one door, the "IsPlayer" condition evaluates true and proceeds as expected to the bottom node. On a duplicated door with no other changes, that condition never evaluates at all, resulting in an OnFinished transition back to the start node. I put a Debug Log at the top of OnCheck on that condition and it never fires.

    Any chance this is another bug?
     

    Attached Files:

    Last edited: Jul 27, 2015
  16. nuverian

    nuverian

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

    Yes, they are evaluated in order they are listed.
    I just created a test case exactly like your setup. FSM asset reference, in 2 different FSMOwners in the scene.
    Everything works as expected though. I have attached the test FSM. Does it work as expected for you?

    Could it be something related to your condition?

    Thanks
     

    Attached Files:

    • FSM.zip
      File size:
      1.3 KB
      Views:
      494
  17. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    Thanks for going through the trouble to reproduce the case–indeed, the FSM you posted works for me. However, I was able to strip my issue down to a barebones project, which I've linked to you. Mine checks for NodeCanvas events in addition to regular conditions, so maybe my issue has something to do with that. Are you up for taking a quick look?

    To reproduce:

    1) Open the Test Scene
    2) Examine the GenericDoor FSM on the Door GameObject
    3) Enter Play mode. Press the "O" key on your keyboard to simulate opening the door. The transitions will evaluate correctly the first time (through the bottom node).
    4) Press the "C" key to simulate closing the door.
    5) Press the "O" key again. The transitions do not evaluate correctly, and they never will again, no matter how many times the door is 'opened' or 'closed'.

    This feels similar to the issue I posted earlier, that you were able to solve by posting some code in ConditionList to comment out. Perhaps it's related?
     
    Last edited: Jul 28, 2015
  18. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Hey,
    So. I took a look at your example. After digging a bit through it, I realized the issue :)
    Your IsPlayer condition, is deriving from your DialogueCondition class, which is set to receive events, and when that is done it YieldReturns false. (Since IsPlayer is not overrideing EvaluateDialogue). Thus the event is also received from IsPlayer exactly the same frame that it also does for the state before it.
    I suppose you don't want IsPlayer to catch events, or at least not the same event that was catched by the state exactly before it.
    I can really go ahead and explain exactly what's going wrong here if you want.
    Let me know

    Cheers!
     
  19. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    So simple. Indeed, after setting it so that IsPlayer derives from ConditionTask like it should, all works well. I'm humbled by your generosity and your patience. Thanks again!
     
  20. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Don't worry about it. I'm glad to be of help to you :)

    Thanks!
     
  21. janiche

    janiche

    Joined:
    Jan 4, 2015
    Posts:
    52
    Could you please make a DialogueTree documentation??, because there is not a documentation about it.
    Like how can I change the text speed or delete the actor name over the dialogue.
     
  22. nuverian

    nuverian

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

    I will add the Dialogue documentation ASAP.
    Meanwhile, I have attached here a Dialogue GUI based on the new Unity's GUI rather than OnGUI, which you can alter to your liking.
    Simply place the prefab included in the scene and you will be good to go.
    You can if you want hide the actor name text object, or change the text speed through the inspector of the prefab.

    This GUI will also be included in the next version.
    If you have any questions please let me know.

    Cheers!
     

    Attached Files:

    hopeful and Async0x42 like this.
  23. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    Hi,

    I have some questions:

    1) Is there any trial or whatever to test the asset before buying?
    2) Why should I buy this instead of PlayMaker? (Please do not take this question as a Asset fight, just want to put my money on the right asset). On the other hand I see a lot of assets being smashed by more mainstream ones (it doesn't matter if the smashed one is better or worse). And it seems playmaker is mainstream in unity world. Anyway, I don't really like the way it does things, so, this is why I'm looking for alternatives.

    I'm a full time programmer so, I'm not looking at this asset in a "hah! I will make my game with no coding!". But more in a structural way. Want to use it to blueprint some flows and delegate the hard stuff to my code.

    Cheers.
     
  24. nuverian

    nuverian

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

    Thanks for your interest in NodeCanvas.
    Unfortunately there is no trial version at the moment. Creating trial versions for unity assets, is a bit of a problematic situation in my opinion. There is though a "Lite" version for the Behaviour Trees module of NC: http://u3d.as/hnh

    I will try to avoid a "versus" discussion, but I can tell you some differences.
    • Apart from FSMs there are also an advanced, full fledged Behaviour Tree system in NodeCanvas :) You can choose to work with FSM, or Behaviour Trees or both, depending on the task at hand.
    • FSMs can have nested FSMs (or even nested Behaviour Trees) for creating Hierarchical systems.
    • Transitions are not only event based as in Playmaker, but rather condition based. So for a transition to happen you directly check some condition instead of having an action that does this, which in turn raise an event for a transition to happen (which I find complicated).
    • NodeCanvas supports all types of variables out of the box.
    • Variables can also be data bound to MonoBehaviour properties, so that when you get/set the variable you instead get/set the bound property, which gives a lot of flexibility and allows easier "fusion" with existing code.
    • Creating and using generic <T> Action and Conditions are also supported in NC, which results in creating much more reusable custom actions and conditions in many cases.
    • There is a quite advanced suite of included Actions and Conditions that allow you to directly interface with existing code (Call Function, Call Static Function, Check Property, Get/Set Property etc)
    • There are by no means the same amount of premade actions and conditions included in NC as there are in Playmaker. Playmaker has far more.
    These are the most prominent differences that come in mind. There are certainly more though.

    As I tend to say, although there is a handfull of premade actions and conditions included, NodeCanvas (or at least for me any similar asset) is really not about magicaly making full games without any coding at all, but rather about visualy organizing behaviours and logic based on structural systems like State Machines and Behaviour Trees in this case :)

    Let me know if you have any questions and I will be glad to answer.

    Cheers!
     
    Last edited: Aug 4, 2015
  25. Async0x42

    Async0x42

    Joined:
    Mar 3, 2015
    Posts:
    104
    Just my input as a newcomer to Unity and visual programming, I find the workflow for NodeCanvas to be much better than other BT/FSM systems. I know PlayMaker is kind of the 'goto' with its popularity, but for me at least, NodeCanvas just clicks, and it's really easy to integrate its BT's and FSMs with my exist existing code. I like having the bulk of my work as actual code, and NodeCanvas makes it a breeze to visually design it while retaining all of my own stuff.

    Porting over any integration packages for other systems such as Behaviour Designer and Playmaker is pretty simple, if there isn't any integration already. The generic types mean you don't need to create custom variables like other systems, and instead just use something like BBParameter<SomeAssetsClass> or BBParameter<Vector3>. Plus nuverian is fast for adding any requests from what I've seen. (be it adding integration with another asset, or feature requests to improve NodeCanvas)

    I was iffy about paying for NodeCanvas at the start, since PlayMaker is so popular, but I saw that Shroud of the Avatar used it (and I grew up on Ultima games haha), and haven't ever regretting my purchase.

    Highly recommend NodeCanvas over other systems I've seen! (Plus you get BT's and FSM, both of which are nicely integrated with each other, I haven't checked out the Dialogue portion of the asset though)
     
  26. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    Nuverian is too modest! Here are some more killer features that clinch it for me:

    The canvas is configurable. I don't really know about PlayMaker, but in NC I can design the information that my nodes present on the canvas pretty much exactly how I want. I also get access to very clean source code (unlike Playmaker, I believe), which lets me extend NC components if I need to.

    I've probably given nuverian a headache or two trying to use both events and conditionals in my FSM, but the point is I can. That's pretty sweet.

    The Blackboard is a pretty great tool, too. I love how NC can create Asset-based or scene-based graphs, which means that the systems are reusable if you need them to be yet don't clutter up your project folders if you don't. The whole shebang can also be imported and exported using JSON, which I imagine opens up lots of really interesting options. Update my FSMs for players remotely? Yes, please!

    Last big perk is how helpful he is here on the forums even after many years maintaining and improving this asset.
     
    Last edited: Aug 4, 2015
  27. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    @Async0x42 and @Marble
    Thanks a lot for your input and nice words guys!
    I really do appreciate it :)
     
  28. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    Thanks for the information.

    Just one more question. I have seen another asset on the store called behaviour Machine (https://www.assetstore.unity3d.com/en/#!/content/20202). It states that can spit c# code from the graphs. I did make a tool like this some years ago for unity but did not continue developing it because I had not time.

    Does Node Canvas use any "VM" to work? For example Playmaker have something like this where vars are not c# native but something like a "bag" in every state machine or global to the system. I really don't like this because form me it is killer to have to access a dictionary or hash map just to set a var.

    Could you bring a bit of light here?.

    Cheers.
     
    Last edited: Aug 5, 2015
  29. nuverian

    nuverian

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

    Variables are stored in a dictionary within the Blackboard. Getting or setting variables is super easy :)
    Code (CSharp):
    1. GetComponent<Blackboard>().SetValue("myFloat", 12.5f);
    2. GetComponent<Blackboard>().GetValue<float>("myFloat");
    Also the Blackboard is part of the FSM/BT Owner game object and not of the FSM/BT itself, which makes it easily accessible.

    Cheers!
     
  30. nuverian

    nuverian

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

    I'm going to submit the new version soon, so here is the change log :)

    Network Sync Variables
    The most important feature this version is that it's now possible to sync blackboard variables across the network using UNET!
    This is simply done by adding the SyncBlackboard component on the game object with the Blackboard to sync. Any blackboard can be synced this way. All variables of supported types not marked as "Protected" (through the variable options), will be synced, the rest will be ignored. So, in the image bellow, only "myBoolean" will be synced.

    SyncBlackboard.png
    The SyncBlackboard component itself doesn't have any inspector options.
    Very worth noting also, is the fact that if a variable is bound to a component property, it will work just fine. So in a sense, the property itself will be synced in this case :)


    The Rest
    • Added new UGUI based Dialogue GUI for Dialogue Trees.
    • Preferred Types List can now be saved/loaded to preset files.
    • The [PopupField] attribute can now be declared with a string path to a static property to fetch the values from.
    • Added OnEnable and OnDisable calls in ConditionTasks which in the case of FSMs these are called when the parent state o the transition assigned the condition, is enabled/disabled.
    • Behaviour Tree Iterator Decorator is now immediate, which means that all iterations happen in the same frame, unless of course the child node returns Running.
    • Fixed Blackboard deserialization error when the serialized variable type is missing.
    • Fixed and old issue where opening graphs in the editor, sometimes the nodes where completely off than the last time the graph was opened. (thus requiring to press "F" to focus the nodes until now).

    Cheers!
     
    hopeful, Async0x42 and Marble like this.
  31. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    @nuverian Hello, I just bought Node Canvas and I have to say the possibilities it offers look really exciting! :)

    I have a newbie question: how do you restart a tree (ie: a sequencer) once it's run through all its options?
     
  32. nuverian

    nuverian

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

    Thanks a lot for your purchase. I am glad you like NodeCanvas thus far! :)

    In the BehaviourTreeOwner inspector there is an option to "Repeat" the Behaviour Tree once completed, which is ON by default. Also there is of course a Repeater Decorator node if you want to selectively repeat a branch.
    But to be honest, I think I have misunderstood your question here :) and if so please let me know.

    Thanks.
     
  33. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    No that was exactly it! I didn't see the "repeat" option. Thank you! :)

    (And be prepared, I may have plenty of other such silly questions!)
     
  34. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Ah :) Glad to know it was THAT repeat. Hehe.
    No question is silly and I'm glad to answer them all.

    Cheers and thanks!
     
  35. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    @nuverian Here's another one: I'm trying to set a vector3 value in the blackboard to be based on the tree owner's position but I can't seem to manage it. SetVariable<Vector3> requires... another Vector3 and I would like to be able to derive the vector3 from the transform's position. Do you know the simplest way to do that?

    Edit: In a nutshell I'm trying to record a transform's position into a Vector3 (in the blackboard) at the start of a sequencer.
     
    Last edited: Aug 11, 2015
  36. nuverian

    nuverian

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

    If you want a Vector3 variable that resemples the owner's position, the best way to do this is to use Data Bound Variables.
    Easier than it sounds, you simply have to click on the Variable Options mini button:
    VariableOptions.png

    and then select "Bind Property/Transform/Position".
    DataBound.png

    Thus, any time to Get "myVector3" in a task or node, you will be getting the transform.position and any time you Set "myVector3", you will be setting the transform.position of the owner :)

    Of course you can do this with any type of variable on any property on any component attached on the owner's game object.

    Doing this through an Action Task is also possible using "Script Control/Get Property" action task and selecting 'Transform.position' as the target property, but using Bound Variables are in my opinion far better to work with, if you want a variable that is in sync with a property.
     
  37. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    Thank you so much! That was exactly what I needed!! :)

    I have to say that it's obvious you put a lot of care and thoughts in developing this asset and I'm having a great time discovering it. Great job!
     
  38. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    You are very welcome and thanks as well !
    I'm very glad to hear that you enjoy NC :)
     
  39. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    @nuverian Hi, I got a new question: I have a transform variable which I discover during game time and store it in the blackboard. And I would like to get the tag of that transform (to do something with the transform if the tag is "valid"). What would be the best way to get the tag?
     
  40. nuverian

    nuverian

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

    You can once again use the "Get Property" Action Task :)
    GetTag.png

    The thing with every Task, is that you can "Override the Agent" by clicking that check box on the right of "Use Self (TYPE)" and then check the radio button to allow a variable dropdown selection. So the steps here are:
    1. Add Get Property Task.
    2. Select Property (Transform.get_tag).
    3. Override Agent with check box.
    4. Click radio button and select transform variable.


    On another note, you can instead of saving the tag and then checking it, check it directly with the "Check Property" Condition Task, thus minimize the work required, if all you need the tag for is to check it.
    So you could have a Condition Node or Conditional Decorator for example, add "Check Property", set it the same way as above and also specify the equality:
    CheckTag.png


    I hope this is what you mean :)
     
  41. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    Thank you that's exactly what I needed!

    Now another question: I'm trying to define a LayerMask for the line of sight condition and I can't find anywhere to set it. I've tried adding one on the black board but I can't find anything there...

    Also: what would be the best way to have an action run once at the very beginning of the game and never repeat after that? Like a "once only" node?

    And a third one: In the case where I have 2 branches and I want them, after a certain point, to do the same thing: Is there a way to "merge" back (or funnel) several branches into one branch?

    And a fourth one: Is there a way to create an enumerator type variable in the black board?

    Fifth one: How can I access a public variable from a script on a transform that I add to the blackboard at runtime?

    Edit: For the "only once" node I stumbled upon the Filter node, which seems to do exactly that!
     
    Last edited: Aug 12, 2015
  42. nuverian

    nuverian

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

    Sorry for the late reply.

    1. If you want to add extra variable types, you just have to open up "Windows/NodeCanvas/Preferred Types Editor". Within there is a list of types. Just add, remove and modify the list to your liking. Any type shown in this list, will be available to add as a variable, or be used in all generic (T) tasks.

    2. Indeed the best way is the Filter node :)

    3. There is no way to merge 2 branches into one and I think this goes a bit beyond of how behaviour trees work in general, where each node strictly has one parent input. Although it is possible to add something like that, I'm quite skeptical about it at the moment. I will have to think a bit more about this.

    4. Similar to the first answer, yes. You just have to add the type in the Preferred Types List :)

    5. I'm not sure if I understand your question correctly here. Sorry. Can you please clarify a bit so that I provide a valid answer?

    Notice about (1) and LayerMasks: There is currently a small issue I just noticed that in short, inspecting a LayerMask will not work correctly. Also the current Line Of Sight Condition tasks does not have a layermask parameter. I will PM you a .unitypackage with both of the above fixed/implemented tomorrow first thing.

    Cheers!
     
  43. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    In the Nested FSM Node, if the last state in that nested FSM graph have a transition that is conditional, even if the state is finished, the Nested FSM graph will not finish with it and will stuck. I have to workaround by creating an empty action node for it to transition to OnFinished, then the graph will finish and return to the mother graph. This is because the way the conditions are checked. Only when there is no condition transition, it will check if the state is finished.
     
  44. janiche

    janiche

    Joined:
    Jan 4, 2015
    Posts:
    52
    Hi, I'm trying to use Target of Line of Sight 2D, but I don't know how can I configure it. I didn't find any documentation about setting conditions for 2D games, because there isn't Navmesh 2D in Unity, except buying Polynav.
    Could you please help me how can I set any node to work with 2D games??.
     
  45. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    Thank you for your reply! :)

    So I went ahead and added Classes>System>Enum as a variable type in the Preferred Types Editor but it just shows up as "(Enum)" in the blackboard. I thought I would be able to define its values (like for lists) but clicking on it doesn't do anything. I'm pretty sure I'm missing something here...

    Regarding my last question: let's say I have a Transform field in the blackboard. This field is empty at start and will be assigned a transform during gameplay (no way to know what it will be before the game runs).

    Once this transform is known I also know it's going ti have a custom component called "MyComponent". And MyComponent has a public float that I need to modify from within a task in the tree.

    So my question is: how can I access this transform's component and its variable?
     
  46. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    @nuverian

    Hi, so after having used Node Canvas for a few hours here are some notes (bug reports and feature requests) which I hope will be useful. But first let me say again that I truly love it! :)

    (I'm on Windows 8.1 and Unity 5.1.1f)

    Bugs:

    1) There is an ambiguation issue with Unity's UI CanvasGroup and Node Canvas's CanvasGroups. Do you think you could address this? Because having to modify all my scripts to include UnityEngine.CanvasGroup just to declare a UI canvas group feels a bit cumbersome (especially because I don't do any calls to Node Canvas's CanvasGroups).

    2) For some reason the duplicate shortcut (CTRL + D) doesn't always work. Sometimes I have to press the shortcut many times, pan the view, select another node, go back to the node, move it a little and then it works again. Also it seems that the shortcut doesn't work anymore if you try to duplicate a node after it was just duplicated (to create multiple copies).

    3) Sometimes, depending on the zoom level, the visible area zone goes away to a crazy distance (and zooms completely out) when exiting game mode. And I have to drag the view from the void in order to see the nodes again.

    4) When plugging a node to the very end of a sequencer with many nodes (so to the right) the node will be added next to last, instead of last. "Shaking" the node a little usually moves the connection to the last plug, as intended.

    5) There are two warnings appearing linked to Node Canvas every time Unity compiles my scripts:

    Assets/NodeCanvas/Framework/_ParadoxNotion (shared)/Design/PartialEditor/GenericInspectorWindow.cs(18,25): warning CS0618: `UnityEditor.EditorWindow.title' is obsolete: `Use titleContent instead (it supports setting a title icon as well).'

    Assets/NodeCanvas/Framework/Design/Editor/Windows/TaskWizardWindow.cs(23,25): warning CS0618: `UnityEditor.EditorWindow.title' is obsolete: `Use titleContent instead (it supports setting a title icon as well).'



    Feature requests:


    1) The way the spline connection lines are connecting to a node's port can be confusing when there are more than a couple of nodes connected. Do you think you could change the color of a spline when its child node is selected? That way it would be much easier to identify where the connection plugs into the parent.

    Here's a mockup of what I mean (with MANY connections to clearly show the effect):



    2) It would be great to be able to delete a connection from the lower end of the spline (so on the child node port) as well as from the parent node port. Right now to disconnect a child node from its faraway parent I have to zoom out, pan the view to find the parent, zoom back in, unplug the connection, pan back down and zoom back in on the child node to keep working.

    3) It would be great to have an option to give a color tint to node groups. That way things would be much clearer when using a bird's eye view. Also, when zooming out if would be really nice if the names of the node groups would remain at a readable size instead of diminishing to an unreadable size.

    Here's another quick mockup of what I mean (just for the colors):

     
  47. nuverian

    nuverian

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

    For an FSM to be considered Finished, and as such return control in the parent FSM in case of a sub-fsm, it must reach a State which has no outgoing transitions at all, regardless if it's a conditional transition or simply an OnFinish transition.
    If a State has an outgoing transition to another State, then it really is not the "last" state of the FSM, since well, it has a transition somewhere, thus there is nothing that justifies it as "last" :)
    So basicaly the way you do this is actually the correct/by-design way if you want to bring the FSM to a Finished situation. Just point it to an empty state, without any outgoing transition, probably naming the state "Finish" as well :)

    Cheers!

    Hello,

    In general, there is a 2D version for every node that needs specific 2D handling, while the rest can work with 2D games the same way.
    Here is an improved version of Line Of Sight 2D condition which includes a parameter for setting a LayerMask with which you can specify layers to take into account. By default, the source gameobject's and target gameobject's collider are not taken into account anyway with this condition.

    Please open up CheckLOS2D.cs and replace the whole contents with this code:
    Code (CSharp):
    1. using System.Linq;
    2. using NodeCanvas.Framework;
    3. using ParadoxNotion.Design;
    4. using UnityEngine;
    5.  
    6. namespace NodeCanvas.Tasks.Conditions{
    7.  
    8.     [Name("Target In Line Of Sight 2D")]
    9.     [Category("GameObject")]
    10.     [Description("Check of agent is in line of sight with target by doing a linecast and optionaly save the distance")]
    11.     public class CheckLOS2D : ConditionTask<Transform> {
    12.  
    13.         [RequiredField]
    14.         public BBParameter<GameObject> LOSTarget;
    15.         public BBParameter<LayerMask> layerMask = (LayerMask)(-1);
    16.         [BlackboardOnly]
    17.         public BBParameter<float> saveDistanceAs;
    18.  
    19.         [GetFromAgent]
    20.         private Collider2D agentCollider;
    21.         private RaycastHit2D[] hits;
    22.  
    23.         protected override string info{
    24.             get {return "LOS with " + LOSTarget.ToString();}
    25.         }
    26.  
    27.         protected override bool OnCheck(){
    28.             hits = Physics2D.LinecastAll(agent.position, LOSTarget.value.transform.position, layerMask.value);
    29.             foreach (var collider in hits.Select(h => h.collider)){
    30.                 if (collider != agentCollider && collider != LOSTarget.value.GetComponent<Collider2D>()){
    31.                     return false;
    32.                 }
    33.             }
    34.             return true;
    35.         }
    36.  
    37.         public override void OnDrawGizmosSelected(){
    38.             if (agent && LOSTarget.value)
    39.                 Gizmos.DrawLine(agent.position, LOSTarget.value.transform.position);
    40.         }
    41.     }
    42. }

    There is no special setup need :)
    If you still have problems after using this condition task, please let me know and I will provide more specifics.

    Thanks!


    Hey,

    You actually have to add the enum itself, like for example "WrapMode", or "KeyCode" not the type System.Enum :)
    All enums are categorized under "enumerations" when you click to add a new type in the Preferred Types editor window.
    After adding you enum type and the coresponding variable, it will show up as a dropdown popup as normal.
    EnumVar.png

    Regarding you other question.
    First of all, with all types you are going to work with in this fashion, you should add it in the Preferred Types list, so that it shows up in the menus. So in this case, you will have to add "MyComponent" in the list. :)

    From there on the workflow is a bit of the usual when dealing with properties, fields, functions on components.
    Considering your example, add a the Set Field (or Set Property if it's a property) action Task.
    Click the checkbox to override the agent.
    Select the transform variable.
    Click "Select Field". If you have added "MyComponent" in the list, you will see in in the selection menu.
    MyComponentSetField.png

    Suggestion: It's better to you GameObject variable types when you can when working with these things (agent override), but it's not mandatory.




    Thanks again :)

    Bugs

    1)
    The CanvasGroup type is in the NodeCanvas.Framework namespace. The conflict would only occur if you have added the "using NodeCanvas.Framework;" directive. I suppose you have? :)

    2) I will take another look at this. Thanks for mentioning

    3) This has been fixed and the position and zoom level are now saved with the graph so it's always the same as last seen.

    4) The Behaviour Tree nodes are always forcefully ordered by their X position relevant to their parent to enforce better design :), so basicaly there is no difference from where you drag the port to connect to. Maybe the UI needs some change there to make this more clear. Is this what you are refering to?

    5) These warnings have also been fixed.


    Requests

    1)
    Although the image is a bit exagerated in number of child nodes :) I went ahead and made incomming connections to be highlighted similar to how outgoing connections are (thicker). If this do not suffice I could also change the coloring in the future.

    2) I just added the ability to disconnect from child nodes too (with usual right clicking)

    3) I've also just made the title of the canvas groups to stay the same regardless of zoom level. I will take a look at coloring as well in the near future :)
    CanvasTitleZoom.gif

    Thanks!
     
  48. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    Hi, I found some bug, but I am not sure it's your bug or Unity 5.2.0 beta 6 bug. The Wait Mouse Pick2D node, if I start from "Everything" mask, and remove some layer, it will still detect the collider from excluded layer. But if I start from "Nothing" and choose every layer except the one I wish to excluded, it will work. If this is not your bug, please tell me and I will report to Unity the beta bug. :)
     
  49. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    Thank you very much for being so proactive! That's really the mark of a great developer! :)

    Regarding the bugs:

    1) Yes, that's exactly what I was doing! But if I remove it and I just try this:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. using NodeCanvas;
    4.  
    5. public class MySpecialClass : MonoBehaviour
    6.    {
    7.    Blackboard myBlackboard;
    8. ...
    Then I get an error that says:

    ...error CS0246: The type or namespace name `Blackboard' could not be found. Are you missing a using directive or an assembly reference?

    So I guess my question is: which namespace should I use in order to access the Blackboard type?

    4) Ah I didn't know this; I though that by choosing the port you were deciding where the node would be plugged. Now that you say that I understand what's happening.

    Finally I just want to say it's fantastic you managed to already do some of the feature requests! It will make using Node Canvas even more enjoyable. Thank you very much for your hard work! :)
     
  50. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    Why don't you specify it clearly which one of the CanvasGroup you want to use? Like NodeCanvas. Framework.CanvasGroup. You don't have to delete the using directive.
     
    Seith likes this.