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
    Thanks a lot!
    Just to keep everyone updated in this thread and for people not thinking that I may be ignoring questions :), this is related to your forum post on the NodeCanvas Forums. where if of course you need any further help, please let me know there!
     
  2. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    ScourgeGames likes this.
  3. Ladace

    Ladace

    Joined:
    Dec 7, 2014
    Posts:
    40
    Hi @nuverian , there's another bug in recent versions.

    `SetProperty` and similar functions only show static properties in the menu when `agent` is NULL or is not currently containing the specific component. (So every time I have to assign `agent` a prefab with that component and select the target property, and reassign `agent` to something else)

    In version 2.8.0
     
    Last edited: Jun 19, 2018
  4. DavidJares

    DavidJares

    Joined:
    Dec 18, 2016
    Posts:
    50
    Hello . I am very happy Nodecanvas/Flowcanvas-customer. Thank you very very much for bringing such an elegant, impressive and well polished tool to unity. You have obviosly put a lot of skill and work into this awesome asset ( as an owner of hundreds of assets, I can tell you for sure that this one IS the number one of assets I will advise to anybody to get - If they would have to chose only one, I'd say Flow- and Nodecanvas ( ok, its actually 2 ). Thank you dear Mr. Developer.
    Nevertheless, I have two questions and One Request.
    1 ) Is it possible at the moment to use Assembly-Definition-Files for Nodecanvas =? I am really trying hard to reduce my compile times, but I cannot put Node/Flowcanvas into an .asmdef because then it starts giving me errors.
    2) I am getting a warning of which I don't know how to get rid of where the use of "tangentMode" is deprecated and should be replaced with Animationutility-methods. You can see the exact message in the attached screenshot.
    3) The one thing that slows down my workspeed with both of the tools is the searchfunction in the menu of a graph ( when you click into a graph, then you either have a choice to click your way through the hierarchy ( often also a bit tedious , but at least it gets you to your destination , or you use the searchfield-dunctionality). I am really not happy about the search-implementation. It doesn't allow regex, and anything similar to intellisense/ autocompletion like VisualStudio-Behaviour. The ouput of a search is laggy and the content of the ouput is quite unstructured and often hard to search through to find what I am actually searching for. This is the only place where the asset would deserve some amount of improvement in my eyes. I mean to maximize the workflowspeed with this system, the fast , easy and supportive search function is what makes it or breaks it in my eyes. I own the Tool Reuniter, which I really love. Helps to find anything fast in a scene or in your assets. hit a shortcut and start typing what youre searching for. every new letter typed in narrows the search. another tool ( Css-like search, very good and cheap as well ) also remebers the last searches and moves those up in new searchproposals. At the end of the day, it is this point in the workflowchain which is a little bit bottlenecking. But maybe I have to get more used to the tool in order to get faster with it, because I just started using it last week and I am probably not using it as efficiently as possible.
    Also when zooming out of the graph the font gets blurry, which is a pitty, but one can live with it.
    All the rest is just phenomenal and I really take a bow in front of you, nuverian. Thank you.
     

    Attached Files:

    nuverian likes this.
  5. TeagansDad

    TeagansDad

    Joined:
    Nov 17, 2012
    Posts:
    957
    @DavidJares - I haven't tried creating an assembly definition for NodeCanvas yet, I have found that it works just fine if you move it into Assets/Plugins (so then it gets compiled into Assembly-CSharp-firstpass).

    You just need to keep any integration packages out of the Plugins folder, unless the asset it is integrating with is also in Plugins.

    If you're getting errors when setting up .asmdefs, it's usually due to files in Editor folders. Any assets with a folder structure like AssetName/Scripts/Feature/Editor will need an .asmdef inside each of those Editor folders, set to exclude all platforms except Editor, and with references to any .asmdefs that the scripts need references to. A better folder structure for this is to have two parallel ones: AssetName/Scripts/Feature and AssetName/Editor/Feature.

    (I'm not at my PC and I don't remember what NC's folder structure looks like. These are just general guidelines for using asmdefs.)
     
    nuverian likes this.
  6. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    395
    I did manage to get NodeCanvas (and SLATE) to work with assembly definition files.
    It took some work to rework the dir structure, but I've been using it for a while now.

    In fact, I've changed all of the asset store packages that I use to use custom assemblies, and it's been great.
    Some I did have to edit a bit, but overall it went fine.


    With the new Incremental Compiler from Unity, splitting the project into multiple assemblies is now finally worth it.
     
    nuverian likes this.
  7. DavidJares

    DavidJares

    Joined:
    Dec 18, 2016
    Posts:
    50
    @TeagansDad @SugoiDev cool , thank you for the fast input. I'll give it a go in the afternoon :D. Also the iterative Compiler i didn't know about seems very tempting.
    So far I had no errors with the editor folders. I thought these errors would only come up when one attempts to make a build, but nut not during development inside the unityeditor. The Unity-Doc doesn't even mention that one should treat Editor-Folders in a different way..
     
    SugoiDev likes this.
  8. nuverian

    nuverian

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

    This was a known bug that has been fixed. Please send me a PM with your email and I will send you the Fix as soon as possible.
    Thank you.


    Hello David.

    Thank you so much for all your kind words and for your such a positive feedback!
    I really appreciate it and I am very glad that you enjoy using NodeCanvas and FlowCanvas!

    Please let me address your questions/requests.

    1. I have personally not yet thoroughly checked Unity's new assembly definitions and how exactly they work out, but thanks to the input of both @TeagansDad and @SugoiDev (thanks guys!) I now have some info to test against and possible re-organize folder structure if need be to make that easier for everyone :)

    2. The easiest way to get that deprecation warning rid of, would be to simply delete the Keyframe_DirectConverter.cs file :) Keyframes will still be serialized correctly with the Reflected_Converter and considering that you do not use a lot of AnimationCurves in your (NodeCanvas) graphs, there would be no performance difference.
    A more complete alternative would be changing the code to this:
    Code (CSharp):
    1. #if !NO_UNITY
    2. using System;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. namespace ParadoxNotion.Serialization.FullSerializer {
    7.     partial class fsConverterRegistrar {
    8.         public static Internal.DirectConverters.Keyframe_DirectConverter Register_Keyframe_DirectConverter;
    9.     }
    10. }
    11.  
    12. namespace ParadoxNotion.Serialization.FullSerializer.Internal.DirectConverters {
    13.     public class Keyframe_DirectConverter : fsDirectConverter<Keyframe> {
    14.         protected override fsResult DoSerialize(Keyframe model, Dictionary<string, fsData> serialized) {
    15.             var result = fsResult.Success;
    16.  
    17.             result += SerializeMember(serialized, null, "time", model.time);
    18.             result += SerializeMember(serialized, null, "value", model.value);
    19.             result += SerializeMember(serialized, null, "inTangent", model.inTangent);
    20.             result += SerializeMember(serialized, null, "outTangent", model.outTangent);
    21.             result += SerializeMember(serialized, null, "outTangent", model.inWeight);
    22.             result += SerializeMember(serialized, null, "outTangent", model.outWeight);
    23.             result += SerializeMember(serialized, null, "outTangent", model.weightedMode);
    24.  
    25.             return result;
    26.         }
    27.  
    28.         protected override fsResult DoDeserialize(Dictionary<string, fsData> data, ref Keyframe model) {
    29.             var result = fsResult.Success;
    30.  
    31.             var t0 = model.time;
    32.             result += DeserializeMember(data, null, "time", out t0);
    33.             model.time = t0;
    34.  
    35.             var t1 = model.value;
    36.             result += DeserializeMember(data, null, "value", out t1);
    37.             model.value = t1;
    38.  
    39.             var t2 = model.inTangent;
    40.             result += DeserializeMember(data, null, "inTangent", out t2);
    41.             model.inTangent = t2;
    42.  
    43.             var t3 = model.outTangent;
    44.             result += DeserializeMember(data, null, "outTangent", out t3);
    45.             model.outTangent = t3;
    46.  
    47.             var t4 = model.inWeight;
    48.             result += DeserializeMember(data, null, "inWeight", out t4);
    49.             model.inWeight = t4;
    50.  
    51.             var t5 = model.outWeight;
    52.             result += DeserializeMember(data, null, "outWeight", out t5);
    53.             model.outWeight = t5;
    54.  
    55.             var t6 = model.weightedMode;
    56.             result += DeserializeMember(data, null, "weightedMode", out t6);
    57.             model.weightedMode = t6;
    58.  
    59.             return result;
    60.         }
    61.  
    62.         public override object CreateInstance(fsData data, Type storageType) {
    63.             return new Keyframe();
    64.         }
    65.     }
    66. }
    67. #endif

    But I really think that simply deleting the Keyframe_DirectConverter.cs file is a better solution, unless you are using a lot of AnimationCurves in your graphs.

    3. I presume you are mostly referring to FlowCanvas since FlowCanvas versus NodeCanvas, has a lot more nodes to browse within. The search functionality in the "Node Browser" has gone by a lot of iterations and there is certainly still room for improvements (like always are). One little trick that you can use to narrow down searches a lot, is to precede/include part of category or type names into your searches.

    For example, if you search for "clip len" you will get this:
    SearchField1.png

    ...while for "str nul" this:
    SearchField2.png
    The way this works, is that each separate word you are typing into the search field, is checked in order of it's appearance against the full path of the elements (meaning full category + name) to show. Thus if you search for "nul str" for example there would be no results, but the inverse of that ("str nul"), will match to "string" and "null" in that order.

    Another example just for clarification.
    "ev up": "ev" matches to the "Events" category, while "up" to Update elements within any depth of that category.
    SearchField3.png

    I find this "trick" to be quite helpful in narrowing down searches a lot, but of course more improvements can always be made!

    Let me know what you think.

    Thanks again for all your positive feedback!
     
    Ladace and SugoiDev like this.
  9. DavidJares

    DavidJares

    Joined:
    Dec 18, 2016
    Posts:
    50
    @nuverian Thank you very much for your explanation. Actually I will be using quite some Animation Curves in that particular Project ( or at least references to them ). Thank you especially for the tipps on how to use the search field more efficiently. That already sounds quite useful.
    Let me just throw some general suggestions into the room which I noticed already last year ( I own your tools for longer, but had not much possibilites to work more indepth with them until now.)
    In Flowcanvas :

    When working with Graphnodes, I would find it more easy to quickly grasp what a node is doing, if there was an option to enable AutoLabeling NodeINPUTS with a text of the pre-node-name and the pre-variable value . ( Similarly like it is done when one connects referenceobjects as inputs ) . That way one would not need to backtrack the wire with your eyes just to find out from which output it came. ( See the example in the attached picture ). As the wire distances and amounts increase, this would really speed up the overview . Maybe a hotkey would suffice to toggle it on / off.
    Additionally, an ability to apply individual Colors to the wires would be cool and maybe easy to realize ?

    Also, One thing that I would appreciate, especially with macros, would be the ability to set the INPUT-Values to default values which will be set when one creates an instance of an macro node, so one does set it up once and does not have to set it up ( and remember ) each time one creates an instance of a macro. It would already suffice to have this for primitives like floats, ints , bools and strings. Just like you can set initial values on membervariables in your scripts.



    Also wanted to thank you for making that code very userfriendly, clean, very well structured and the best : easy to extend ( with a very good documentation ) . As a computer science student for 4 years, I am asking myself how many years of development experience you already gained in order to be able to deliver such quality.
    One Question I have remains : How about performance ? There must be a lot of reflection going on, which rings some alarm bells in my ears. How optimized is it and - more importantly -what should we avoid when relying on this tool for gamedev( talking about flowcanvas)?

    Btw:
    I really like the ability to edit in playmode, noc waiting no compiling, experimenting and letting ideas flow . When I like what I created , just save to JSON and then after playmode-exit reimport the JSON , that way I can keep my changes whenever I want to do so .awesome.

    Somehow we have to make unity pay you a million and buy you out with this hravyweight unreal-blueprints-competitor.
     

    Attached Files:

  10. DavidJares

    DavidJares

    Joined:
    Dec 18, 2016
    Posts:
    50
    Last suggestion for the searching: It is confusing that after typing in a string and then a space-character, then the list shows nothing ->then I start thinking it didnt find anything
    . Also what I would really suggest ist to save/cache the past search -entries which the user finally clicked on and prioritize them / put them on top of the searchresult-list. for example when I multiple times used transform translate, then whenever i start typing transform or translate, the transform-translate-entry should be somewhere at the top of my list. maybe the user might help with this by holding some extra key while clicking the entry, in order to tell the system that that was the thing he was searching for and the system would next time remember this info and utilize it to prioritize search results. I have to add that I didnt really start utilizing the Favorites-Feature yet. maybe I am asking for features that are already there... so I apologize in advance,

    These were many suggestions which I just wanted to let you know would make this really powerful plugin even more powerful in my eyes, almost perfect to say. The search is really the corepoint. ( I can only advise you to have a look at reuniter ( this is the second tool I would advise to anyone using unity, it cuts down so much of my time because I dont need to navigate through the project and scenes anymore to find what I am searching for .) The search there is really well implemented. It also provides a hotkey to show a list of the last searches.

    I really don't want to criticize your work, I just can see it so close to being a 6-star-Asset which just needs more discoverage on the asset-store ( Mainly more Videos - even usergenerated ones - on youtube should really amplify your sales ).
    Thank you for all your hard work and years of development , support and passion.
    Best regards, David. Wish a good n8 to all ;)
     
  11. Ladace

    Ladace

    Joined:
    Dec 7, 2014
    Posts:
    40
    @nuverian Cool. I can wait for the new release with that patch
    Also, I found it quite annoying when I drag to reorder actions in a node, which swaps the action I'm dragging with the one at the target position, rather than inserting. I believe it makes much more sense for inserting than swaping.

     
  12. Censureret

    Censureret

    Joined:
    Jan 3, 2017
    Posts:
    363
    Hey, guys, I have this very odd bug.

    This is how my tree looks normally:

    upload_2018-7-16_22-7-41.png

    Now as you can see I have an interrupter that checks if the closest enemy is null (meaning it is destroyed)

    However, something funny happens when it is destroyed as you can see below

    upload_2018-7-16_21-29-21.png

    instead of interrupting it does something odd to the node and of course throws a lot of errors in my console.

    Can anyone tell me what I've done wrong?
     
  13. PsyKaw

    PsyKaw

    Joined:
    Aug 16, 2012
    Posts:
    102
    You have to check this in your task:
    Code (CSharp):
    1. if (ClosestEnemy == null)
    2.     EndAction(false);
    If you can post the entire code of Seek task and the error log, it could be easier to help you.
     
    nuverian likes this.
  14. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    @Everyone Please use the NodeCanvas Official Forums for support. It is impossible to keep track of support questions in this monolithic thread and thus I rarely check this thread. If you want faster support, once again, please use the NodeCanvas Official Forums (or email). Thank you!

    Re-ordering was indeed a bug which has already been fixed. Please take a look at this post from @PsyKaw for a manual fix, or alternatively if you want to, I can send you the whole file for your convenience (just PM me an email to send the file to :) ).

    Thanks!

    Hello,
    Can you please post the errors that are thrown in the console? Otherwise I can't know what went wrong :)
    Also, please consider making a post about the problem you are facing or any other possibly future problem or question in the NodeCanvas forums, where I will be able to help you much faster.

    Thank you!
     
  15. RedMattis

    RedMattis

    Joined:
    Apr 18, 2015
    Posts:
    33
    Sorry if this has been asked, but...

    Is NodeCanvas good for creating behaviour trees?

    Does it support stuff like dynamically changing the tree during runtime; appending a branch structure to make tool to hunt when the AI gets hungry; resorting the behaviour tree priorities when the AI's health is low; that sort of thing? Can I expand on/write my own nodes for it if, say I want a sequence node that can either restart every run if its child returns running, or jump directly to that node.

    I'm quite happy writing my game in C# generally, but getting an overview of the trees when they are all just a bunch of script files in a folder can be a bit tricky.
     
  16. Carpe-Denius

    Carpe-Denius

    Joined:
    May 17, 2013
    Posts:
    842
    NodeCanvas was made for this. It is mature, easy to use, has some nice specials (automatically create nodes via reflection without having to create hundreds of one-line-actions), the possibility to use storage on the game object or scene-wide (for all entities or for Entity groups)..

    I don't know if it supports building trees at runtime, but your question sounds like it wouldn't be necessary anyway. You can build subtrees and only use them if needed.
     
    nuverian likes this.
  17. RedMattis

    RedMattis

    Joined:
    Apr 18, 2015
    Posts:
    33
    What if, say, the AI, when searching for food comes across a locked house. In that case you'd want to append the test-different-ways-to-get-into-building subtree into the currently active food-search subtree. Same for if it is looking for a crafting regent, etc.

    The idea is to have a rather simple tree, but let it dynamically grow and shrink depending on what requirements the AI has.

    Do you know if NodeCanvas can resort subtrees? Say the 'get food is prio 5.0, but the AI gets really hungry so the priority should be bumped up to prio 9.0 so it will ignore other subtrees (given that the food subtree returns success/running) it was working in favour of getting food. It is pretty easy to do this kind of thing is straight C#, I'd just run a sort on the list of tree nodes based on the 'priority' value.
     
  18. Carpe-Denius

    Carpe-Denius

    Joined:
    May 17, 2013
    Posts:
    842
    You can make your own "use subnodes by priority"-selector pretty easily.

    Your "get into building" thing sounds more like "goal oriented action planning", which is not possible as far as I know. But you could make your own "goal planner selector" and use the rest of nodecanvas as children of the selector. It is probably not the best way to reuse it, but maybe possible.


    Edit: turns out, there is already a priority selector included.
     
    Last edited: Sep 5, 2018
    nuverian likes this.
  19. RedMattis

    RedMattis

    Joined:
    Apr 18, 2015
    Posts:
    33
    Perfect!

    Yeah, writing a goal-planner shouldn't be difficult, but that wasn't really the point. The point is to have a dynamic tree.

    A (very) simplified AI could f.ex. have a main tree that says something like:

    Selector Main
    --Sequence FoodCheck
    ----Inverter
    ------Leaf IsHungry
    ----Leaf EatFood

    When something (the player?) tells the AI to craft a chair it would append a subtree (with a priority) along the lines of...

    // Craft a specific item
    Sequence CraftItem
    --Leaf GetValidRecipes // Success if a recipe exists. Populates Selector below
    --PopSelector(?) EvalulateRecipe // Remove from selector if it fails. Fails if empty
    ----Sequence EvalulateRecipe
    ----Leaf AddToPerformRecipe
    --PopSelector(?) PerformRecipe // Remove from selector if it fails. Fails if empty
    ---- Sequence CompleteRecipe

    // Check if recipe can be completed
    Sequence EvalulateRecipe
    --Leaf RecipeIsPossible

    // Collect components and craft item
    Sequence CompleteRecipe
    --Leaf PopulateObtainAllItems // Populates below
    --Sequence ObtainAllItems
    ----ObtainItem
    --Leaf CompleteCrafting // Makes the item.

    // Obtain an item, possibly through crafting.
    Sequence ObtainItem
    --Selector FetchOrMakeRecipeItem // Goal Planner-type sorting favoring least effort.
    ----Sequence FetchItem
    ----Sequence CraftItem // (same as "Craft a specific item" above)

    What this all means is that when told to make a chair, if there is multiple recipes the AI will check them all in order until it finds one it can complete (AttemptRecipe -> RecipeIsPossible). When it has done so it will collect the items it requires, if an item cannot be found, it will attempt to craft that in turn (thus making this recursive). If all items were obtained it will craft the item, if not it will fail. Regardless of outcome the initial "CraftItem" will be removed.

    I've written something along these lines in C#, but my solution is probably a bit unorthodox, and I would love something more readable at a glance :)

    PS. If anyone has other ideas for how to solve this kind of case I'd love to hear them. :)
     
  20. Carpe-Denius

    Carpe-Denius

    Joined:
    May 17, 2013
    Posts:
    842
    If you take your time and make your own goal planning selector node, you could use it without "dynamically adding subtrees", just put all possible trees as children of the goal planning node and let the selector select (thats what you have programmed it for) which child to execute next based on some kind of a* pathfinding over the child cost.
     
    nuverian likes this.
  21. RedMattis

    RedMattis

    Joined:
    Apr 18, 2015
    Posts:
    33
    That wouldn't be recursive though, or am I misunderstanding you?
     
  22. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
  23. local306

    local306

    Joined:
    Feb 28, 2016
    Posts:
    155
    Hi @nuverian. I'm having a lot of fun with NodeCanvas and designer agent behaviours.

    One question I have for you is how would one safely destroy a game object that an agent is using as a target for pathfinding?

    I've tried to safeguard as much as possible by checking for nulls once the target object is destroyed (from no health for example), but I still end up with infinite loop problems because a referenced object no longer exists and perhaps that these nodes seem to run on coroutines which may not necessarily reflect the current state of the game.
     
  24. nuverian

    nuverian

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

    Thanks. I am glad you like NodeCanvas!

    Just to clarify, nodes to not run on coroutines, so this is certainly not the problem, but an order of execution could be in some cases :)

    Can you please share a bit more information about how/when you destroy the gameobject as well as the null checks?
    Are you destroying the gameobject from within the graph itself, or through some other part of your code?
    Are you doing the null checks using the existing conditions or within some custom condition?

    Ideally, you should be able to do something like this.
    DynamicCheckNull.png

    Notice that the Conditional Decorator above, is set to be "Dynamic". This means that the condition is evaluated continuously per-frame. If the Conditional was not set to be "Dynamic", then the Wander action (in this example) would continue running even though the condition is no longer true (meaning that "myGameObject" has become null).
    Please note, that the ConditionTask used here, is specifically the "CheckUnityObject", rather than the generic "CheckVariable(T)". This is important, because the "CheckUnityObject" condition handles UnityEngine Objects in a special required way to determine whether or not they are actually null.

    Please let me know.
    Thanks!
     
  25. local306

    local306

    Joined:
    Feb 28, 2016
    Posts:
    155
    Thanks for the reply @nuverian. Funny enough, I spent some more time checking around and came across the CheckUnityObject instead of the variable and got it working as you mentioned. Everything is in order now :)
     
  26. Hellhound_01

    Hellhound_01

    Joined:
    Mar 5, 2016
    Posts:
    102
    Hi @nuverian. I have recently started to use behaviours trees for my AI and must say, that NodeCanvas is impressive! Top notch work, keep it on, I have a lot of fun with NodeCanvas.

    Because I'm new to behaviour trees I'm actually struggling with some basic questions. I hope someone of you could point me to the right direction.

    In my set up I've a military squad where some members could have different behaviours (leader, scout, medic, support ect.) for each I've to set up a separated behaviour tree, sometimes I've group orders/behaviours, sometimes I've special orders/behaviours for single members. I.e. the medic stops attack to help injured members. And I think I could solve this perfectly with NodeCanvas. But how I've to handle different variants in that tree?

    I.e. each member has a gun and should attack with it. I've different variants of those guns (rifle, SMG, LMG ect.) which comes with different configurations (sounds, muzzle flashes, animations). Most of this variants could handled by variables, but sometimes those guns have special behaviours and conditions. I.e. a bolt-rifle could only fire a single shot, a gas based action rifle could fire a single shot and burst until the clip is empty. If the clip is empty I've to play sometimes a special sound. A LMG could be only fired on phrone postion, shoulderered by two men
    or layered on an obstacle. As you can see, many possiblity, many conditions ...

    How I have to set up this? I see different possiblilies:

    1. Set up for each gun variant a sub behaviour tree.
    2. Set up for each gun variant a simple state machine.
    3. Write for each gun variant a specific action task which combines many actions (play animation, sound, particle system, conditions) ....
    4. Write a standard c# class and call a function by events and retrigger the tree by events if completed and block the tree until notification.

    Point 4 looks to dirty for me. What is the most appropriate way to handle this?
     
    Last edited: Sep 25, 2018
  27. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087

    Hello,

    Thanks a lot! I am really glad you like using NodeCanvas! :)

    Hmm. I actually think that the most dirty solution of the four, would be #3 since if you are going to write custom action task for the variant, you could as well just write standard c# functions for them and doing the call through Execute Function, which will have the added bonus of being re-usable among the rest of the codebase in your project, versus usable only by NC.

    With that said, and depending on the complexity/difference of the variants, I believe that using SubTrees (or SubFSMs depending on how you want to model the logic), would be a good approach, since it actually is the closest thing graphs have to any sort of inheritance.

    One quite nice feature in NC that I think not a lot of people are using, is the fact that SubGraphs can also be set in runtime through the use of standard Blackboard Variables. As such, you could create a single branch in the root BT that leads to calling the SubTree (node), and that SubTree node can load and execute a BT Asset, fetched from a Blackboard Variable. You will of course need to have some sort of initializing that Blackboard Variable based on the variant SubTree you want to use.

    Alternatively, you could always of course just add all SubTrees in the root BT and use some condition to determine which of the SubTrees to execute based on the variant you want to use. In this case, probably the best way to do this, would be by using the Switch (enum) Composite in my opinion.

    SwitchEnum.png

    You will of course need to create the enum and add it in the Preferred Types Editor, but that only needs to be done once :) This solution is also probably easier than the solution stated above (having one SubTree node with dynamic assignment from variable).

    Let me know if that helps or works for you.
    Thanks!
     
    kyuskoj likes this.
  28. Hellhound_01

    Hellhound_01

    Joined:
    Mar 5, 2016
    Posts:
    102
    Hi @nuverian,

    I think this could be the solution to all my Problems, thanks for your detailed explanations, I will give it a try. It sounds to me to be the best solution :cool:
     
  29. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    You are very welcome! :)
     
  30. WonderWorkshop

    WonderWorkshop

    Joined:
    Aug 28, 2014
    Posts:
    7
    Hi @nuverian , I recently bought node canvas and I like it a lot. But today I found the support website is down. So I cannot check the documents. Do you know when it will be up?
     
    AwkwardScience likes this.
  31. AlenH

    AlenH

    Joined:
    Jun 30, 2015
    Posts:
    42
    Seems I cant acess publisher website, anyone else have the same problem?
     
  32. net8floz

    net8floz

    Joined:
    Oct 21, 2017
    Posts:
    37
    @AlenH the website seems to be back up
     
    AlenH likes this.
  33. blacksun666

    blacksun666

    Joined:
    Dec 17, 2015
    Posts:
    214
    Still down for me, ERR_CONNECTION_TIMED_OUT
     
  34. AlenH

    AlenH

    Joined:
    Jun 30, 2015
    Posts:
    42
    yep still down...
     
  35. nuverian

    nuverian

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

    I just woke up to see that the websites are down. I have contacted the host service just now and hope that is is resolved ASAP! I am sorry for the inconvenience.
     
    AwkwardScience and AlenH like this.
  36. MaximilianPs

    MaximilianPs

    Joined:
    Nov 7, 2011
    Posts:
    322
    can we rise an "event" based on Azure[Sky] ?
    For example spawning NPC from a gameobject from a certain clock time (coming from Azure[Sky]) and getting back at a certain clock time always coming from Azure[Sky]? :D
     
  37. nuverian

    nuverian

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

    I haven't used Azure[Sky], but right now NodeCanvas "Check Event" tasks, only support events of type 'System.Action' or 'System.Action<T>'. If Azure[Sky] 's events are such as these, then yes, otherwise unfortunately no :)
    This is something I plan to change for the better and to be able to hook into any type of event by the way instead of only System.Action in the future.

    Thanks!
     
  38. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Just in case anyone missed it, the new version 2.8.5, has recently gone live. One of the nice things of the new version, is the new Utility Window called "Finder", which can be opened from the GraphEditor toolbar.

    That new utility window (which you can dock on the right side of the GraphEditor), basically lists a flat hierarchy of the nodes, connection, tasks and parameters of the graph, within which you can quickly search and find in the search field at the top and click select items to jump the GraphEditor to the relevant element.

    This can of course be a huge time saver if you want to find all nodes where you are using a specific variable, or a specific task for example!

    ElementFinder.gif

    In later versions, I plan to improve on this new window for displaying errors as well as refactoring where possible.
    I hope you like it :)

    Cheers!
     
  39. MaximilianPs

    MaximilianPs

    Joined:
    Nov 7, 2011
    Posts:
    322

    I've found this tut. Where he turn on/off the light based on clock... I guess I can accesso to it too, ins't it? :)
     
  40. Alic

    Alic

    Joined:
    Aug 6, 2013
    Posts:
    137
    hey, haven't used node canvas in a while. Some of my old code with an old version was doing stuff like this inside custom actions:

    Code (CSharp):
    1. ((CombatAIManager)agent).CurrentCombatant_SelectCommandWithTarget(CommandIndex.value, Target.value);
    This doesn't seem to work anymore, and I can't find any documentation on scripting and custom agent types. Should I make CombatAIManager a blackboard variable? Should I be using the graph without a graph owner component? Basically, what are the new best practices for getting to the object that in this case is going to be executing most of my actions?


    Another way of asking my question is, are graph owners now supposed to be the only type of agent? Or should I be able to pass in any component type as an agent?

    Thanks a lot for your time!
     
    Last edited: Oct 18, 2018
  41. Alic

    Alic

    Joined:
    Aug 6, 2013
    Posts:
    137
    Hey, ignore my last question: somehow I had missed that generics are used to define the action’s agent type.

    New question:
    Everything is working great and building behavior trees is a lot of fun, except for one thing. When play mode first starts there seems to be a random chance that onexecute will be called in the actions of a graph owner before awake has been called by other components on the same object. This means a lot of null references when get component hasn’t been called yet (In awake) on a component which the action is trying to reference. Is there any automatic way to make sure the graph won’t start up until after awake is called, or do I have to disable the start on enable behavior on the graph owner and write a custom component to start the graph going in start()?
     
    Last edited: Oct 28, 2018
  42. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Sorry for the late reply (please use the official forums since I reply there much more frequently of course) :)
    While I don't have Azure[Sky], I can presume that the properties you see in the inspector of the Azure[Sky] component are most than probably possible to access in NodeCanvas (if they are serialized in the component itself) with the CheckProperty condition or GetProperty action for example, and thus based on that condition or property value do something in an NodeCanvas BT or FSM :)
    If you want, please drop by the NodeCanvas forums and start a thread and I will do my best you help you out.
    Thanks!

    Hey,
    Indeed, this is an issue introduced lately due to some changes. I basically moved the "first execution" from OnStart, to OnEnable, when I shouldn't. This is something I have already changed for the next version. If you want, I can send you the changes (please send me PM with an email). Another alternative would be to change the BehaviourTreeOwner and FSMOwner script execution order in the Unity's Script Execution Order, putting them anything above "Default Time".
    I think it would be better though to just send you the changes if you want :)

    Thanks!
     
    Alic likes this.
  43. Alic

    Alic

    Joined:
    Aug 6, 2013
    Posts:
    137
    No worries, I worked around it for now, which wasn't difficult since my own game scripts have limited exposure to node canvas stuff. I'll just wait for the Asset store update. Thanks for the response, and my bad for using the wrong forum, in the future I'll post on your official forums.

    Working with Node canvas been great so far, it's looking like I'll use it in actual production at this point!
     
    nuverian likes this.
  44. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello everyone. The new version 2.9 has recently gone live on the asset store!

    Due to major files and folder restructure, you should please remove the previous installation folder and re-import NodeCanvas anew.

    Here are the changes:
    • New: Major files and folders restructure. This also allows usage of Unity Assembly Definitions.
    • New: Connection source node can now also be re-linked in all graph modules.
    • New: The Minimap now also shows connections, as well as selected nodes and execution status.
    • New: Blackboard Variables can now be duplicated (through a variable’s options button).
    • New: Action/Condition Lists, now display listed task names when the “Show Summary Info” pref option is disabled. This can help a lot in saving very wide node spacing.
    • Mod: First graph execution is now OnStart instead of OnEnable.
    • Mod: Stepped and Linear connection visual modes are removed.
    • Mod: Connections are now easier to click.
    • Mod: Complete refactor of StyleSheets.
    • Mod: Removed source PSD files for icons.
    • Mod: Removed the old QuickStart.pdf file (it was getting quite old and hard to keep up to date).
    • Mod: Some general improvements to GUI styles, icons and colors.
    • Fix: BT Filter Decorator when used in a SubTree.
    • Fix: Nodes GUI size is now always relevant to it’s content.
    • Fix: Ocasional GUI connections flickering when using node inspector.

    Unless a hotfix is required, next version will most probably be version 3.0 along with some major improvements, changes, major requests, as well as new features!

    Cheers!
     
    Last edited: Nov 7, 2018
    Alic likes this.
  45. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    Hi all,

    This is a bit of a strange question, but can NodeCanvas somehow offer us these options:

    - Disable auto DontDestroyOnLoad for MonoManager?
    - Allow manual spawning of MonoManager?

    I would love to control the lifecycle of NodeCanvas and FlowCanvas myself if possible.

    Thx
     
  46. Caruos

    Caruos

    Joined:
    Dec 30, 2016
    Posts:
    42
    Hello,
    I purchased NodeCanvas during Black Friday, and I intend to combine its Dialogue System with I2 Localization.

    I found this module intended to link NodeCanvas and I2 Localization. I made a new project with NodeCanvas and I2 Localization, and I put the additional module folder in the Assets directory. I can't compile because I get the following error messages :

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/Dialogue/I2Say.cs(26,120): error CS1061: Type `I2.Loc.LanguageSource' does not contain a definition for `GetTranslation' and no extension method `GetTranslation' of type `I2.Loc.LanguageSource' could be found. Are you missing an assembly reference?

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/Dialogue/I2Say.cs(43,33): error CS0117: `ParadoxNotion.Design.EditorUtils' does not contain a definition for `BBParameterField'

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/Dialogue/I2Say.cs(53,64): error CS1061: Type `I2.Loc.LanguageSource' does not contain a definition for `GetTermsList' and no extension method `GetTermsList' of type `I2.Loc.LanguageSource' could be found. Are you missing an assembly reference?

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/Dialogue/I2SayRandom.cs(23,114): error CS1061: Type `I2.Loc.LanguageSource' does not contain a definition for `GetTranslation' and no extension method `GetTranslation' of type `I2.Loc.LanguageSource' could be found. Are you missing an assembly reference?

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/Dialogue/I2SayRandom.cs(70,64): error CS1061: Type `I2.Loc.LanguageSource' does not contain a definition for `GetTermsList' and no extension method `GetTermsList' of type `I2.Loc.LanguageSource' could be found. Are you missing an assembly reference?

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/I2GetTranslation.cs(26,129): error CS1061: Type `I2.Loc.LanguageSource' does not contain a definition for `GetTranslation' and no extension method `GetTranslation' of type `I2.Loc.LanguageSource' could be found. Are you missing an assembly reference?

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/I2GetTranslation.cs(39,42): error CS0117: `ParadoxNotion.Design.EditorUtils' does not contain a definition for `BBParameterField'

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/I2GetTranslation.cs(41,41): error CS0117: `ParadoxNotion.Design.EditorUtils' does not contain a definition for `BBParameterField'

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/I2GetTranslation.cs(47,36): error CS0117: `ParadoxNotion.Design.EditorUtils' does not contain a definition for `BBParameterField'

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/I2GetTranslation.cs(50,39): error CS0117: `ParadoxNotion.Design.EditorUtils' does not contain a definition for `BBParameterField'

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/I2GetTranslation.cs(55,73): error CS1061: Type `I2.Loc.LanguageSource' does not contain a definition for `GetTermsList' and no extension method `GetTermsList' of type `I2.Loc.LanguageSource' could be found. Are you missing an assembly reference?

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/I2SetTerm.cs(51,42): error CS0117: `ParadoxNotion.Design.EditorUtils' does not contain a definition for `BBParameterField'

    Assets/NodeCanvas-I2Localization-master/unity-project/Assets/NodeCanvas Integrations/I2 Localization/Tasks/Actions/I2SetTerm.cs(54,47): error CS1061: Type `I2.Loc.LanguageSource' does not contain a definition for `GetTermsList' and no extension method `GetTermsList' of type `I2.Loc.LanguageSource' could be found. Are you missing an assembly reference?

    I presume this is because the module was created in January 2018, and the NodeCanvas 2.9 update changed the structure. Could you please tell me how to change/move scripts to make the module work with I2 Localization ?
     
  47. nuverian

    nuverian

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

    That is a strange request indeed :)
    Because MonoManager is a very core part of the framework and in the way it's working, may I ask what is the end goal/use case more precisely and how it currently is an issue? With the end goal known, there might be another solution (or different changes) possible to achieve it.
    Let me know. Thanks.

    Hey,

    Most of the errors shown here seem to actually be from I2 API changes rather than NodeCanvas. There is only one NodeCanvas API error/change here, that being `ParadoxNotion.Design.EditorUtils' does not contain a definition for `BBParameterField'. To fix this error, please change the occurences,

    From:
    Code (CSharp):
    1. EditorUtils.BBParameterField
    To:
    Code (CSharp):
    1. BBParameterEditor.ParameterField
    Unfortunately I don't really own I2 right now to help with the I2 related API changes. :-/
    Thanks.
     
    Caruos likes this.
  48. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    We are trying to control the game loop through events, and would like to tell NC and FC things like:

    - now it's time to spawn your MonoManager.
    - now it's time to pause all graphs.

    It's not a huge problem, but NC and FC are the only assets we use that manages its own lifecycle, aka by spawning MonoManager at runtime. Letting us create the MonoManager ourself and enable/disable it would be a good thing.

    As for avoiding DontDestroyOnLoad, it is simply how we prefer to manage a scene (not having persistence objects), and we plan to only have 1 scene as so far all contents are dynamic, so DontDestroyOnLoad is really just an overkill :) (We don't even use it with Rewired)

    (I assume, MonoManager is just a "process" that run all graphs in a scene, and without it, all graphs are just data, I am not sure if this is a correct assumption.)
     
  49. Caruos

    Caruos

    Joined:
    Dec 30, 2016
    Posts:
    42
    Thanks a lot for your answer !
    By following your advice (and the advice on the I2 Localization thread), I managed to compile ! I'll try it out and keep you updated, I'm really excited by all the possibilities !
     
    nuverian likes this.
  50. guybro_thunderboots

    guybro_thunderboots

    Joined:
    Aug 27, 2015
    Posts:
    45
    Is the "Timeout" decorator broken?

    I've noticed this strange behavior: if the Timeout decorator times out, failing child node, then the next time the BT comes across that Timeout decorator, it will immediately timeout instead of restarting the timer. On the 3rd time we enter the Timeout decorator, though, the timer starts properly.

    Shot of affected part of BT attached. Don't worry about "Fire Weapon," it never fails.

    upload_2018-12-10_16-35-4.png