Search Unity

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

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

  1. vesoljc

    vesoljc

    Joined:
    Nov 18, 2013
    Posts:
    8
    I'm having an issue with the latest version 1.50. I'm also on 4.5 unity.

    Assets/NodeCanvas/Core/Other/EditorUtils.cs(33,70): error CS0122: `UnityEditor.EditorGUIUtility.IconContent(string)' is inaccessible due to its protection level

    The unity documentation says that this exists, however in code, it does not exist... any ideas?
     
  2. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    That is most weird. I'm also on Unity 4.5 and clearly that method exists :)
    Is that the only error you get? I wish I had a better answer right now.
     
  3. bkw

    bkw

    Joined:
    Sep 20, 2013
    Posts:
    49
    Nice update! Don't know when you added it, but the lower CPU usage when the editor is open is much appreciated!

    Just to make sure, with the new BBComponent specific types thing, in script we still need to to a cast to access the data right? (eg. bbVar.value as Rigidbody) The extra type = typeof(Rigidbody) (for example), is just to put a restriction in the editor?

    No luck with BBComponentList? If this is the case, what's the proper way of exposing a regular Object variable in a task? (like a BBObject)

    Btw, when deleting a blackboard variable, it still uses NO! and DO IT in the buttons. =)
     
  4. bkw

    bkw

    Joined:
    Sep 20, 2013
    Posts:
    49
    While updating my code to the new 1.5 stuff, I'm running into a change I don't know how to fix.

    I'm trying to store a List<MyClass> on the blackboard. Previously I created a blackboard variable of type System.Object, then in script, I assigned it with blackboard.SetDataValue("listVarName", myMyClassList). This doesn't work anymore since in GetData of Blackboard.cs, the check is ofType.IsAssignableFrom(data.dataType) (versus the commented out data.dataType.IsAssignableFrom(ofType)). It'll create a new variable instead of using the one I already created. What should be the proper way to store a custom type on the blackboard now?

    (Is it still difficult to create a custom BBVariable type? I recall it wasn't easy before, but not sure if all your changes to this point has made it simpler.)
     
  5. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey there,
    Thanks. The lower CPU editor is there long time now :)

    Yes, you will have to cast the BBComponent since the serialized type if Component. This is mostly an editor thing for restriction and avoiding errors by possible designer :) .I could add a generic GetValue<T>() to avoid that, but I think it would be an overkill. Alternative you could create your own BBVariables. For example:


    Code (CSharp):
    1. namespace NodeCanvas.Variables{
    2.  
    3.     [Serializable]
    4.     public class BBRigidbody : BBVariable{
    5.      
    6.         [SerializeField]
    7.         private Rigidbody _value;
    8.         public Rigidbody value{
    9.             get {return useBlackboard? Read<Rigidbody>() : _value ;}
    10.             set {if (useBlackboard) Write(value); else _value = value;}
    11.         }
    12.     }
    13. }
    Thats the base template. just replace the type with another Component derived type. Then this will allow selection of a Rigidbody type from the Blackboard and will not need casting.

    Sorry, I omited the the List<Component>. I will make sure it makes in the next version and similar to the Component variable you will be able to select a specific derived type.

    Heh, yeah it still does say DO IT :) I hope it's the only DO IT i forgot. The graph owner removal no longer says so :p



    I had commented this out thinking it might be prone to errors while doing some refactoring, but I don't think it will anymore and will work as expected, meaning as before. Please uncomment it and add it to the check. I will do the same.

    As far as custom BBVariable deriving Component type, it is as simple as the posted code above. Regarding a System.Object derived type though, you could do something similar:

    Code (CSharp):
    1.     [Serializable]
    2.     public class MyClass{
    3.         public string text;
    4.         public float number;
    5.     }
    6.  
    7.  
    8.     [Serializable]
    9.     public class BBMyClass : BBVariable{
    10.      
    11.         [SerializeField]
    12.         private MyClass _value;
    13.         public MyClass value{
    14.             get {return useBlackboard? Read<MyClass>() : _value ;}
    15.             set {if (useBlackboard) Write(value); else _value = value;}
    16.         }
    17.     }
    And it will even show in the task inspector,
    But, the dropdown will never work correctly. I will have to add a type selection similar to the one that the Component have on the blackboard and then it will work fine :)
     
  6. desyashasyi

    desyashasyi

    Joined:
    Nov 22, 2012
    Posts:
    73
    Hii.. Nuverian,
    It is long time since I commented here :).

    I own others dialog plugin for unity, but i studied that your dialog tree is simple but powerful, and the important thing is suitable for my workflow. Regarding to it, i have some questions.

    1. Is it possible to have a collection of dialog tree? so i can reuse it in the future scenes. How to do that? as far as i know, the dialog tree data is not in a specific database/file but compiled with the others resources of the scene in unity asset.

    2. In my game project, I want to provide a dialog between physical character (with 3d character) and virtual character (only appearing their thougt). What is the best way? It is OK to attach actor name to empty game object? In the same way, i need to provide a highlight/news appear in the GUI to inform some task/just information to player with the specific condition. For instance, my project is about learning of disaster response, Player will have an information about a number of victims, scale of disaster etc, if an earthquake or others type of disasters occurred.

    3. Is there any NGUI example scene for dialog tree? :).

    Thanks
     
    Last edited: Jun 19, 2014
  7. desyashasyi

    desyashasyi

    Joined:
    Nov 22, 2012
    Posts:
    73
    I have another issue. I tried to show dialog using NGUI. I want to make dialog tree paused if there is not NGUI event controlled by playmaker.

    Is it OK if I use following method?

    1. I need playmaker action (when NGUI component has clicked) to set BBBool in Dialog Tree owner from FALSE to TRUE.Should i creating custom action in playmaker?

    2. In NC Dialog tree, I need action to check the value of BBBool, If the value is TRUE then dialog will continue to next node, if the value is FALSE, It is waiting a specific time before continue to next node. Then the value of BBBool will be re-set to FALSE.

    What is your suggestion for this problem?

    Thanks.
     
    Last edited: Jun 19, 2014
  8. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087

    Hello,
    I'm glad you like it :)

    1. You can save the dialogue tree as a prefab and use it in any scene :)

    2. It is fine to have DialogueActor on empty game objects of course.. In your case you could have the 'Thought' actor on the same gameobject as the real actor as well. Alternatively you could use the meta data information to specify if the said dialogue is thought or not and keep it to the same actor, but that would require you modifying/creating custom UI to make use of that meta.
    For the information hightlights, I would create a custom action like 'Show Info' which will somehow inform a UI to show it. I could provide you more info if you want to use the included EventHandler for that, or you could do it without it.

    3. No, there is not an NGUI example now, but I could create one :)


    1. To set a blackboard bool variable when an NGUI button has clicked and within playmaker, yeah you should be best of creating a playmaker action, or some other script :)

    2. There is a Condition node for dialogue trees which executes the first child if the condition assigned is true else executes the second. You can assign a CheckBoolean in there and do something like the following.

    Exmaple.png

    #2 is a Condition node, 3 is a Say node, 5 is an Action node with an action list


    Is that what you mean or I'm completely off?
    :)
     
    Last edited: Jun 19, 2014
  9. desyashasyi

    desyashasyi

    Joined:
    Nov 22, 2012
    Posts:
    73
    Hii... Thanks a lot for your explanation. Yes you answered my questions :).

    For the information hightlights, I would create a custom action like 'Show Info' which will somehow inform a UI to show it. I could provide you more info if you want to use the included EventHandler for that, or you could do it without it.

    Ahh... Thank you, because i did not do anything now :).

    However, I was updated to NC 1.5.0, Playmaker 1.7.7.2 and now i am using Unity 4.5.1. After i extracted NC Playmaker actions, I got this error.

    1.png

    I followed Playmaker developer suggestion to put using Tooltip = HutongGames.PlayMaker.TooltipAttribute; The problems was resolved, but i got another error

    2.png

    I replaced

    checkBool = EditorUtils.BBValueField("CheckBool", checkBool) asBBBool;

    by

    checkBool = EditorUtils.BBVariableField("Check Bool", checkBool) asBBBool;

    The error is gone, but i am wondering that the solution is true. Thanks.
     
    Last edited: Jun 19, 2014
  10. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Yes the solution is totaly correct and those errors are my mistake.
    I will have to push an minor update to fix that.

    Thanks
     
  11. Adalberto_VL

    Adalberto_VL

    Joined:
    Mar 7, 2013
    Posts:
    11
    Hello nuverian,

    I am also getting the same error as @vesoljc after updating to 1.50. I'm also on 4.5 unity.

    Assets/NodeCanvas/Core/Other/(33,70): error CS0122: `UnityEditor.EditorGUIUtility.IconContent(string)' is inaccessible due to its protection level

    It seems the problem is in the icon content lines?
     
  12. nuverian

    nuverian

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

    I am trying to find whats wrong on that. I am also on Unity 4.5.1
    A fast solution to get along the error is to replace in those lines with "= GUIContent.none" for now, but of course you will miss some icons until I find out whats happening

    Sorry about it.
     
    Last edited: Jun 20, 2014
  13. desyashasyi

    desyashasyi

    Joined:
    Nov 22, 2012
    Posts:
    73
    Hi Nuverian,
    I want to continue my issues. I was tied a blackboard to the dialog tree as follow:

    1.png

    But when i clicked a node, The blackboard is not tie.

    2.png

    When i come back to the unity inspector, the blackboard assigned to dialog tree is also gone.

    4.png

    Is it bug? How to solve?

    Another question is about get and set BBBool variable. Maybe because i got trouble with the blackboard, i confused how to check BBBool Variable (condition) and to set BBBool variable (action). Is it only type the variable name of BB? Can I assign a variable in others BB?

    5.png .

    Thanks.
     

    Attached Files:

    • 3.png
      3.png
      File size:
      54.4 KB
      Views:
      892
  14. nuverian

    nuverian

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

    I will really need to fix the light theme very soon. Also I wonder why the textures seem compressed. Do they always show as such?

    With that said, let's see your issues:

    Your DialogueActor component on the 'FieldCommander' game object is probably missing the blackboard assignment. If you assign a blackboard to the DialogueActor component there, then the blackboard will show up. It currently disapears when selecting the node because whenever a node is selected the blackboard reference that shows up is taken from the selected actor for the node (top of inspector). So if the currently viewing node has an actor selected that doesn't have a blackboard, the reference is gone.

    actor.png

    Can you please verify that your DialogueActor component has a blackboard reference assigned or not?
    Of course the blackboard doesn't have to be on the same game object. It can be anywhere and even share the same one between more than one Dialogue Actors.

    As soon as the blackboard reference correctly shows up, then when you select the node, the control on the Set/Check Variables will change and allow you a visual selection for the variable.

    node.png


    As a side note, I see that you have entered an actor named "Commander" in your Dialogue Tree. If this is the same as the one on the 'FieldCommander' game object like the screen I've posted, then you dont need to assign that on the semi-transparent fields reading 'current references' on the Dialogue Tree. You simply have to select the Commander actor in the dropdown selection at the top of the node or any other Dialogue Actor you've entered.

    actorSelected.png

    Please let me know if I answered your questions or you have any trouble :)

    Thanks
     
  15. desyashasyi

    desyashasyi

    Joined:
    Nov 22, 2012
    Posts:
    73
    Ah... I missed something. Now solved!

    Sorry bothering you :).
     
  16. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Don't mention it.
    Glad to know everything is ok :)
     
  17. desyashasyi

    desyashasyi

    Joined:
    Nov 22, 2012
    Posts:
    73
    View attachment 104551

    Hii Nuverian,
    I was tried your suggestion as above picture. But it does'nt fit completely to my need :) .

    Actually, I want to have the ability to detect NGUI event during waiting time. So my idea is how to execute Node 2 and Node 5 in same time (parallel). For instance, i provide 5 second to wait. If the timer is fired, execution will continue to next node. At the same time, if player make an NGUI event (e.g. button click), it will passed the timer and execute next node. Is it possible and how to implemented it?

    Oo.. I think i need a feature to duplicate nodes. In current NC (based on My experience), it can only duplicate node by node. So, is it possible to duplicate a selection of some nodes?
     
    Last edited: Jun 20, 2014
  18. nuverian

    nuverian

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

    There are various ways to do that, but the single most easy way would be to create a custom action, considering that you also want to wait for some time before timeout-ing, Here is the action :)

    Code (CSharp):
    1. using UnityEngine;
    2. using NodeCanvas.Variables;
    3.  
    4. namespace NodeCanvas.Actions{
    5.  
    6.     [Category("NGUI")]
    7.     public class TimeoutButton : ActionTask {
    8.  
    9.         public BBFloat timeout;
    10.         [RequiredField]
    11.         public UIButton button;
    12.  
    13.         protected override void OnExecute(){
    14.             UIEventListener.Get(button.gameObject).onClick += Clicked;
    15.         }
    16.  
    17.         void Clicked(GameObject go){
    18.             EndAction();
    19.         }
    20.  
    21.         protected override void OnUpdate(){
    22.  
    23.             if (elapsedTime >= timeout.value)
    24.                 EndAction();
    25.         }
    26.  
    27.         protected override void OnStop(){
    28.             UIEventListener.Get(button.gameObject).onClick -= Clicked;
    29.         }
    30.     }
    31. }
    Drag and drop the NGUI button, set a timeout and when the button is clicked or time has passed, the action will end and as such in the context of Dialogue Tree the Action node will continue to the next node.

    Notice that I just call EndAction instead of EndAction(bool) true or false, which defaults to true. In the context of dialogue trees an action ending in failure will stop the dialogue tree.

    I will add more 'official' support for NGUI soon and provide the Tasks in the online resource.
    Let me know if everything works out for you.


    Best regards,
    Gavalakis

    (PS: Unfortunately rectangle selection is not here yet )
     
  19. desyashasyi

    desyashasyi

    Joined:
    Nov 22, 2012
    Posts:
    73
    Hi Nuverian,
    Thank you for quick response, i am very glad. However, i also already have the custom action. But i don't know this is match or no to the standard of Nodecanvas custom action, because I just combined Wait.cs, CheckPlaymakerBool.cs and modify last file to SetPlaymakerBool. So, i want to confirm it.

    I using Playmaker Bool variable as a control. It is set to TRUE/FALSE value when NGUI event fired. In NC, this variable will be checked when Node "Say" executed, and it will automatically set the Playmaker Bool variable with opposite value. In the same time, timer will start on the defined time. When It is fired, Playmaker Bool variable also will be set to the opposite value.

    However, I will try your way :).

    Thanks.

    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using UnityEditor;
    3. #endif
    4.  
    5. using UnityEngine;
    6. using System.Collections.Generic;
    7. using HutongGames.PlayMaker;
    8. using NodeCanvas.Variables;
    9.  
    10. namespace NodeCanvas.Actions{
    11.  
    12.     [Category("PlayMaker")]
    13.     [Description("Check and Set Playmaker bool during waiting time")]
    14.     public class WaitAndDetectBool : ActionTask {
    15.  
    16.  
    17.         [RequiredField]
    18.         public PlayMakerFSM playmakerFSM;
    19.         [RequiredField]
    20.         public string boolName;
    21.      
    22.         public BBBool checkBool;
    23.  
    24.         public BBFloat waitTime = new BBFloat{value = 15};
    25.  
    26.         protected override string info{
    27.  
    28.             get
    29.             {
    30.                 if (playmakerFSM == null)
    31.                     return "No PlayMakerFSM Selected";
    32.  
    33.                 return "Get PlayMaker Bool '" + boolName + "' == " + checkBool + "\nSet PlayMaker Bool '" + boolName + "' == " + !checkBool.value  + "\nWait " + waitTime + " sec.";
    34.             }
    35.         }
    36.  
    37.  
    38.  
    39.  
    40.         protected override void OnUpdate(){
    41.             bool pmBool = playmakerFSM.FsmVariables.GetFsmBool(boolName).Value;
    42.  
    43.             Debug.Log ("boolName : " + pmBool + " CheckBool : " + checkBool.value );
    44.             if ((elapsedTime >= waitTime.value) || (pmBool == checkBool.value)){
    45.                 playmakerFSM.FsmVariables.GetFsmBool(boolName).Value = !checkBool.value;
    46.                 EndAction ();
    47.             }
    48.            
    49.         }
    50.  
    51.  
    52.  
    53.  
    54.         ////////////////////////////////////////
    55.         ///////////GUI AND EDITOR STUFF/////////
    56.         ////////////////////////////////////////
    57.         #if UNITY_EDITOR
    58.      
    59.         protected override void OnTaskInspectorGUI(){
    60.          
    61.             playmakerFSM = EditorGUILayout.ObjectField("PlayMakerFSM", playmakerFSM, typeof(PlayMakerFSM), true) as PlayMakerFSM;
    62.          
    63.             if (playmakerFSM == null)
    64.                 return;
    65.          
    66.             FsmBool[] boolVariables = playmakerFSM.FsmVariables.BoolVariables;
    67.             List<string> boolNames = new List<string>();
    68.             foreach(FsmBool boolVar in boolVariables)
    69.                 boolNames.Add(boolVar.Name);
    70.          
    71.             boolName = EditorUtils.StringPopup("PlayMaker Bool", boolName, boolNames);
    72.             //checkBool = EditorUtils.BBValueField("Check Bool", checkBool) as BBBool;
    73.             checkBool = EditorUtils.BBVariableField("Check Bool", checkBool) as BBBool;
    74.  
    75.             waitTime  = EditorUtils.BBVariableField("wait Time ", waitTime ) as BBFloat;
    76.         }
    77.      
    78.         #endif
    79.     }
    80. }
     
    Last edited: Jun 20, 2014
  20. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087

    Well, like I said there can be many ways to do what you were after and you found your own :)
    Personaly though, I prefer more self contained tasks. Are you going through playmaker for the sole reason of picking up that NGUI event? Cause it might be an overkill if you do. Unless there are more stuff in that PM FSM, I suggest you try the example task posted above :)

    In the end though, it's a matter of preference ;)
     
  21. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548

    Hi there!;)

    I'm having the same problem, but my Unity version is 4.3.4f1.

    I've changed the line as you said and everything works fine!

    Again thanks for the new folder relocation. It is a lot easier to move them to get JS working!

    Cheers!
     
    Last edited: Jun 21, 2014
  22. desyashasyi

    desyashasyi

    Joined:
    Nov 22, 2012
    Posts:
    73
    Hii nuverian,
    I am trying to turn off default typewriter effect in NC dialog tree, and I want replace it with NGUI typewriter. How to achieve this?. Because when i tried to attach typewriter effect script in the NGUI label, it doesn't work. Is it also possible to tackle all of NGUI event and component using current NC? Thanks.
     
    Last edited: Jun 22, 2014
  23. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey there,
    You are welcome. The issue is correctly fixed for the next version.

    Cheers!

    Hello,

    No part of the UI is part of the Dialogue Tree. The UI is completly decoupled and as such if you want to use the NGUI typewriter or NGUI at all for that matter, you will have to create your own UI which is not that hard actually.
    The communication is done through an EventHandler; a messanger. The Dialogue dispatches some events which the UI will have to subscribe to and make use of.

    Here is a very simple NGUI subtitles using the typewriter. Put this on a game object and assign the UILabel which should have a TypewritterEffect as well.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using NodeCanvas.DialogueTrees;
    4.  
    5. public class NGUISubtitles : MonoBehaviour {
    6.  
    7.     public UILabel label;
    8.  
    9.     private TypewriterEffect typer;
    10.     private DialogueSpeechInfo dialogue;
    11.  
    12.     void OnEnable(){
    13.         NodeCanvas.EventHandler.Subscribe(this, DLGEvents.OnActorSpeaking);
    14.     }
    15.     void OnDisable(){
    16.         NodeCanvas.EventHandler.Unsubscribe(this);
    17.     }
    18.  
    19.     void Awake(){
    20.         typer = label.GetComponent<TypewriterEffect>();
    21.         label.enabled = false;
    22.         typer.enabled = false;
    23.     }
    24.  
    25.     void OnActorSpeaking(DialogueSpeechInfo dialogue){
    26.  
    27.         this.dialogue = dialogue;
    28.         label.text = dialogue.statement.text;
    29.         label.enabled = true;
    30.         typer.enabled = true;
    31.         StartCoroutine(WaitTyper());
    32.     }
    33.  
    34.     IEnumerator WaitTyper(){
    35.  
    36.         yield return null;
    37.         while (label.text != dialogue.statement.text)
    38.             yield return null;
    39.  
    40.         yield return new WaitForSeconds(1.2f);
    41.  
    42.         label.enabled = false;
    43.         typer.enabled = false;
    44.         dialogue.DoneSpeaking();
    45.     }
    46. }
    Here are a bit more info in case you haven't seen yet.
    The Subscribe/Unsubscribe could of course also be done through a UI "manager" in case you have any.

    I am not really sure what you mean if NC is possible to tackle NGUI :)
     
    Last edited: Jun 22, 2014
  24. FullySikbro

    FullySikbro

    Joined:
    Feb 20, 2014
    Posts:
    4
    Hey nurevian i have a problem with nodecanva, the problem im having is, im trying to double jump but the problem im having is that it transition to jump and double jump at the same time and also have infinte loop error.
     

    Attached Files:

  25. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Hi nuverian!

    I'm fighting with the Action Task creation(In JS#). Right now it is going well. I've done the first one i need that moves a character to a destination using mecanim with root motion and navmesh. Great and working!!

    Now i have some problems. Setting the category of the task doesn't seem to work in the latest version.
    And the important thing. I want to go deeper and i'm having some problems with the BBVariables. Specially the BBGameObjectList. I need to assign a list of game objects from OverlapSphere to a BBGameObjectList variable or add one by one if it is possible. But watching some of the tasks included with uses lists, i can't get the code right(In JS# ovbiously). It would be nice if you could add some reference in the documentation. I know that C# is far more used, but it will be really appreciated.

    For now, if you could post the move to position task converted, it would be great! :D With that, i could move forward without problem.(or until the next problem! ;))


    Cheers!
     
  26. desyashasyi

    desyashasyi

    Joined:
    Nov 22, 2012
    Posts:
    73
    Hi Nuverian,
    I am not so good in programming, so i prefer to use playmaker and similar plugin.:)

    After, i studied your example action for NGUI, i think i need to write more action in NC for NGUI. Sorry for the term of 'tackle' :). I mean, with current NC, is it possible to create all of needed action for NGUI?

    I was implemented the example of dialog subtitle (DialogueSubtitlesGUI.cs) with a little modification for NGUI. And it is succeeded shows all dialog node without problems, But i want to replace the typewriter effect with NGUI typewriter effect (fading effect, etc.).

    deafult.png

    Then, i tried your action code for NGUI posted in #473. But the execution of dialog node is stop if the text in this node is very long. I tried to modify the coroutine in WaitTyper(), but no effect.

    NGUI vers.png

    Thanks...
     
  27. adex0909

    adex0909

    Joined:
    Jul 8, 2012
    Posts:
    2
    I found problem my project using NodeCanvas.
    I fix the method "MoveToLocation::OnStop()" in NodeCanvas.

    protected override void OnStop(){
    lastRequest = Vector3.zero;
    navAgent.avoidancePriority = 0;
    if (navAgent.gameObject.activeSelf) => if (navAgent.enabled)
    navAgent.ResetPath();
    }

    May I fix it? Do you think it is no problem?
     
  28. nuverian

    nuverian

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

    I've changed when transitions are cheched in version 1.4.8. Transitions of a state are checked before it even enters and if any is true, it happens immediately.

    So what is probably going on here is that, when you press Space, the Collision Stay transition on state 'Jump' is already true. As such the Jump never Enters, the transition to Idle happens immediately and because it's the same frame, the KeyDown Space is already true, and thus an infinete loop in made.

    Maybe I will add this kind of immediate behaviour as an option. For now you can comment out lines 69-70 in FSMState.cs

    Let me know if everything works as expected.

    Hello,

    I will definetely add documentation on the website for working with JS
    The attribute name for category has changed in latest version. It is now simply 'Category'. You should get a warning if you use the old one. Here is the JS code you asked:

    Code (JavaScript):
    1. #pragma strict
    2. import NodeCanvas;
    3. import NodeCanvas.Variables;
    4.  
    5. @Category("Movement")
    6. @Name("MoveJS")
    7. @Task.AgentType(NavMeshAgent)
    8. class MoveToPosition extends ActionTask{
    9.  
    10.     public var targetPosition:BBVector;
    11.     public var speed:BBFloat;
    12.     public var keepDistance:float;
    13.     private var lastRequest:Vector3;
    14.  
    15.     private function get navAgent():NavMeshAgent{
    16.         return agent as NavMeshAgent;
    17.     }
    18.  
    19.     override function get info():String{
    20.         return "GoTo " + targetPosition;
    21.     }
    22.  
    23.     override function OnExecute(){
    24.  
    25.         navAgent.speed = speed.value;
    26.         if ( (navAgent.transform.position - targetPosition.value).magnitude < navAgent.stoppingDistance + keepDistance ){
    27.             EndAction(true);
    28.             return;
    29.         }
    30.  
    31.         Go();
    32.     }
    33.  
    34.     override function OnUpdate(){
    35.         Go();
    36.     }
    37.  
    38.     override function OnStop(){
    39.         lastRequest = Vector3.zero;
    40.         if (navAgent.enabled)
    41.             navAgent.ResetPath();
    42.     }
    43.  
    44.     override function OnPause(){
    45.         OnStop();
    46.     }
    47.  
    48.     private function Go(){
    49.  
    50.         if (lastRequest != targetPosition.value){
    51.             if (!navAgent.SetDestination(targetPosition.value)){
    52.                 EndAction(false);
    53.                 return;
    54.             }
    55.         }
    56.  
    57.         lastRequest = targetPosition.value;
    58.         if (!navAgent.pathPending && navAgent.remainingDistance <= navAgent.stoppingDistance + keepDistance)
    59.             EndAction(true);
    60.     }
    61. }

    And here is the OverlapShpere in JS since you asked about lists.

    You can use Linq in JS
    Code (JavaScript):
    1. #pragma strict
    2.  
    3. import NodeCanvas;
    4. import NodeCanvas.Variables;
    5. import System.Linq;
    6.  
    7. @Name("Get Overlap Sphere JS")
    8. @Category("Physics")
    9. @Task.AgentType(Transform)
    10. class GetOverlapSphereObjects extends ActionTask{
    11.  
    12.     public var layerMask:LayerMask = -1;
    13.     public var radius:BBFloat;
    14.     public var saveObjectsAs:BBGameObjectList;
    15.  
    16.     override function OnExecute(){
    17.  
    18.         var hitColliders = Physics.OverlapSphere(agent.transform.position, radius.value, layerMask.value);
    19.         saveObjectsAs.value = hitColliders.Select(function(c) c.gameObject).ToList();
    20.         saveObjectsAs.value.Remove(agent.gameObject);
    21.  
    22.         if (saveObjectsAs.value.Count == 0){
    23.             EndAction(false);
    24.             return;
    25.         }
    26.  
    27.         EndAction(true);
    28.     }
    29. }
    Without Linq you could simply do that
    Code (JavaScript):
    1.         for (var c in hitColliders)
    2.             saveObjectsAs.value.Add(c.gameObject);


    Hello,
    Sure there is no reason not to be able to write actions or condition that tackle :p with NGUI. As said before, I will provide such Tasks sortly as well.

    As far as the subtitles dialogue stopping earlier, I think you have both the sample GUI and the NGUI subtitles in there. Remove the DialogueSubtitlesGUI comonent if you are going to use the the NGUI subtitles provided above or any other subtitles GUI for that matter.

    Let me know if that's the case, cause it works with long texts as well. Also take a look at the code posted above again, since I've editied a bit after I posted it. I've added a yield before the while in WaitTyper coroutine.

    Hello,
    Sure go ahead. That's no problem :)
     
    Last edited: Jun 23, 2014
  29. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    NICE!!!!!!!!


    Thanks nuverian!

    Awesome code samples for reference!
    I can see that you can mix Unity Variables with BBVariables. So the problems i'm having may be because the code i'm writing is totally wrong. I'll study these scripts to learn more! :p

    Cheers!
     
  30. msl_manni

    msl_manni

    Joined:
    Jul 5, 2011
    Posts:
    272
    It is much better to work in NodeCanvas with c#.
    I have been able to adapt to c# easily with NC code examples.
    And when you are writing your own code is of very small amount then it is better to learn/adapt to c# itself. :)
     
  31. FullySikbro

    FullySikbro

    Joined:
    Feb 20, 2014
    Posts:
    4
     
  32. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548

    Thanks man! I now, but i've something personal with C# ;)

    I don't have much time for scripting, and i can't spend the few moments i have in learning/converting to C#. Maybe some day, but now i have a lot of work done learning UnityScript.

    You are totally right, and i really want to do it, but now i can't! :p

    Cheers!
     
  33. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    You are welcome :)
    Just make sure you access the variable through the .value property instead of them directly.
    So for a BBFloat, it's not speed = 4. it's speed.value = 4.
    Maybe I'll add an operator to allow doing the first as well.

    I've done the same thing that you did, except from the condition that returns from Jump to Idle.
    Even if I add a condition on Jump > Idle, that is always true, with the code commented, it will simply return to the Idle state immediately.

    DoubleJump.gif

    Is it at all possible for you to send me a small replicating project that this error apears?

    Thanks
     
  34. msl_manni

    msl_manni

    Joined:
    Jul 5, 2011
    Posts:
    272
    Can the following be converted to a generic variable setter for all BB variable types? A single function to set any variable type - float, bool, int .............


    Code (CSharp):
    1.  
    2. using NodeCanvas;
    3. using NodeCanvas.Variables;
    4.  
    5. namespace NodeCanvas.Actions{
    6.  
    7.     [Category("✫MyFunctions")]
    8.  
    9.     public class SetOtherBlackboardBool : ActionTask {
    10.        
    11.         [RequiredField]
    12.         public BBGameObject target;
    13.  
    14.         [RequiredField]
    15.         public string targetVariableName;
    16.  
    17.         [RequiredField]
    18.         public BBBool setTo;
    19.        
    20.         protected override void OnExecute(){
    21.            
    22.             target.value.GetComponent<Blackboard>().SetDataValue(targetVariableName, setTo.value);
    23.             EndAction();
    24.         }
    25.     }
    26. }
    27.  
     
  35. FullySikbro

    FullySikbro

    Joined:
    Feb 20, 2014
    Posts:
    4
    Ok i think i had a bug with unity and it didn't work so well so i made a new project and it works fine now, thanks for trying to help me
     
  36. HDD

    HDD

    Joined:
    Apr 7, 2014
    Posts:
    3
    Hey Nuverian, I've run into an issue with your otherwise great Node Canvas Behaviour Tree. I duplicated an AI character within my editor and suddenly the original copy is now returning this error:

    <b>Graph Error:</b> 'Infinite Loop Detected. Node ID: 1 will not execute to prevent stack overflow.' On node '<color=#b3ff7f>SELECTOR</color>' ID 1 | On graph 'Skeleton_Knight_AI'

    The strange thing is that the duplicate, which is using the exact same BT is running completely fine. Any help you can offer is appreciated.

     
    Last edited: Jun 24, 2014
  37. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Here is one rather dirty solution. On the other hand you can use the new global variables to read, write to any blackboard, but in that case you don't get to choose it by a variable like here, but rather by it's name.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Linq;
    3. using NodeCanvas;
    4. using NodeCanvas.Variables;
    5. namespace NodeCanvas.Actions{
    6.     [Category("✫MyFunctions")]
    7.     public class SetOtherBBVariable : ActionTask {
    8.  
    9.         [RequiredField] [RequiresComponent(typeof(Blackboard))]
    10.         public BBGameObject target;
    11.         [RequiredField]
    12.         public string targetVariableName;
    13.  
    14.         [SerializeField]
    15.         private BBVariableSet variableSet = new BBVariableSet();
    16.  
    17.         protected override void OnExecute(){
    18.      
    19.             target.value.GetComponent<Blackboard>().SetDataValue(targetVariableName, variableSet.selectedObjectValue);
    20.             EndAction();
    21.         }
    22.  
    23.         ////////////////////////////////////////
    24.         ///////////GUI AND EDITOR STUFF/////////
    25.         ////////////////////////////////////////
    26.         #if UNITY_EDITOR
    27.    
    28.         [SerializeField]
    29.         private int selectedIndex;
    30.  
    31.         protected override void OnTaskInspectorGUI(){
    32.  
    33.             DrawDefaultInspector();
    34.             selectedIndex = UnityEditor.EditorGUILayout.Popup("Type", selectedIndex, variableSet.availableTypes.Select(t => EditorUtils.TypeName(t)).ToArray());
    35.             variableSet.selectedType = variableSet.availableTypes[selectedIndex];
    36.             if (variableSet.selectedBBVariable != null && variableSet.selectedType != typeof(Component))
    37.                 EditorUtils.BBVariableField("Value", variableSet.selectedBBVariable);
    38.         }
    39.    
    40.         #endif
    41.     }
    42. }


    If you re encounter the issue, please do send me a project, There might be a bug there that I don't know of.

    Hello.

    Do you possible get any other errors apart from that within the errors stack? Like a required field that is missing, or an agent that can't be found or anything similar regarding Graph Init?

    Do you get the error once or continuesly?

    Please let me know.

    By the way, just to let you know, you do not need the Sequencers there since they have only one child, but maybe you already know that.



    Finaly, to everyone. To fix the UI images when working in non deskrop build, please do the following:
    Select all the editor images and in the import settings select TrueColor in default. This is something that I've omited. Thanks


    allTextures.png importSettings.png
     
    Last edited: Jun 24, 2014
    msl_manni and HDD like this.
  38. HDD

    HDD

    Joined:
    Apr 7, 2014
    Posts:
    3
    Hey Nuverian, thanks for the reply. The Sequencers were just left over from some changes I had made to the tree, but thanks for reminding me to remove them.

    I seem to have solved the issue thanks to your suggestion, there ended up being an embarrassingly simple solution which I overlooked due to lack of sleep. Thank you for the support regardless.
     
  39. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Thanks for letting me know it's sorted out and there wasn't a nasty bug hiding somewhere :)

    Cheers
     
  40. msl_manni

    msl_manni

    Joined:
    Jul 5, 2011
    Posts:
    272
    Thanks very much for the "Dirty Solution". :D It is always better to have many solutions to each problem. Thanks.:cool:
    And I think its better than Global Vars.

    Can you tell what are you working on now? Whats coming up?:rolleyes:
     
  41. doongame

    doongame

    Joined:
    Jun 4, 2014
    Posts:
    2
    Great job ! I like this stuff !
    Make game developing much easier.
     
  42. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    You are welcome.
    Of course the above said action is quite different than global variables. They do different things. With the above action you can just set a blackbaord variable or could be made to also get a variable, but with global blackboards you can read a variable from within ANY task directly. So for example the MoveToObject, you could select to move to a game object variable that is in another blackboard wihthout the need to first get it localy and then use it, which defies the reasoning behind global blackboard after all :) Regarding you questions I'll post whats up in a bit

    Thanks! Glad you like it
     
  43. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    So here is what I'm submiting and what's new, changed, fixed or imrpoved:

    Workflow
    Dragging a connection out in open canvas will pop the menu for node selection and will automaticaly connect the new node if one is selected. This speeds up the workflow quite a bit.

    DirectMenu.gif
    Variables!
    Added BBComponentList and BBObjectList.
    Added whole lot of BBVariables you can use: BBMaterial, BBTexture2D, BBRigidbody etc
    These work in conjuction with the UnityObject blackboard variable that can be set to any type deriving Unity Object.

    It is now extremely easy to create a BBVariable type especialy if it derives from Unity Object. Actually this is the code :p:
    Code (CSharp):
    1.  
    2.     [Serializable]
    3.     public class BBAudioClip : BBUnityObject<AudioClip>{}
    4.  
    If it doesn't derive Unity Object it's 4 lines more as before.

    Similarily its extremely easy to create you own blackboard variable data. Here is a list of a rigidbodies variable data
    Code (CSharp):
    1.     public class RigidbodyListData : VariableData{
    2.         public List<Rigidbody> value;
    3.     }
    Ok that was it :). It will now show up when adding variables.

    You can of course have non Unity Object variables. For example:
    Code (CSharp):
    1. [Serializable]
    2. public class Hero{
    3.     public string name;
    4.     public int level;
    5. }
    6.  
    7. public class HeroData : VariableData{
    8.     public Hero value;
    9. }
    10.  
    Now the nice thing is that you will get to inspect it in the blackboard through a new editor window
    CustomVar.png

    Of course it could be a list of heroes as well.. Also inspected:

    CustomVarListPopup.png
    So, if you do not care about saving and loading in the sense of blackboard save/load (which I really think few people do use), then that's all you need to do. If you do it might be a few lines more, but for the above example it's not even one more to even save and load :)

    More Script Control
    Added a new task, 'Implemented Action'.
    What this does is that it allows you to further keep your functionality implementation within your own scripts living on your agent game object. It will show a list of all function that have a signature of public State NAME(){}.
    The task will execute that function while it's active and you will have to return the current state of the action. For example:
    Code (CSharp):
    1. public class Example : MonoBehaviour {
    2.  
    3.     public State DoAction(){
    4.  
    5.         if (Input.GetKeyDown(KeyCode.Alpha1))
    6.             return State.Success;
    7.  
    8.         if (Input.GetKeyDown(KeyCode.Alpha2))
    9.             return State.Failure;
    10.  
    11.         transform.Translate(0,0,1);
    12.         return State.Running;
    13.     }
    14. }
    Using this along with the existing CheckFunction (and rest of Script Control Tasks), it is possible to simply keep everything within your own scripts if you want so.

    Behaviour Trees
    I'm working on some ideas on morphing/mutating the behaviour tree at runtime. The first step in this was that behaviour tree nodes can now be labeled/tagged and there is of course the relevant API for finding nodes based on that on top of their name or IDs, so that the more daring can interact with the behaviour tree in more 'internal' ways

    To justify the intention there are 2 new 'Mutating' nodes.
    Toggler: which allows to Disable, Enable or Toggle one or more nodes altogether. The nodes are fetched by their tag names
    Switcher: which allows to switch the root node (at runtime of course). Again the node is fetched by a tag name.

    There are more similar ideas that I am yet thinking over.
    A simple example follows, but I remember someone asked how to do this :)

    Switcher.png

    Furthermore
    More refactoring for better API
    The graph info will now show on the top left instead of top middle and only when no node is selected.
    Removed some UI coloring.
    Fixed the FSM connections when in step mode so that now they are not badly jugged.
    Fixed platform depended import settings for textures.
    Fixed Playmaker<>NC actions compile errors.
    Fixed error in EditorUtils regarding non accessible methods.
    Oh, and there is grid background as shown in the images above.


    That's it for now. I will submit the version tomorrow.

    Cheers and have fun!
     
    DanielSnd likes this.
  44. msl_manni

    msl_manni

    Joined:
    Jul 5, 2011
    Posts:
    272
    "Dirty Solution" vs "Global Variables"
    I am using the Dirty Solution mostly because of I am using it for runtime object manipulation, which are instantiated in-game.:) Global Vars are good if you use them in Editor itself. Correct me if I am wrong.:oops:

    The BB Types and BB List are welcome addition to NC, Much needed thing.:D

    Toggler and Switcher seem good addons. They should be available for FSM and NestedBT too. In FSM it can be used to create unique behavior branches and toggle or switched at runtime. :cool: Maybe used for cutscene branches too. If trigger entered then cutscene2 . Cutscene2 finished then return to playerControl.............................:rolleyes:
     
  45. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    I'm just beginning to realize how easy it is to create my own customized nodes and connections, GUI and all. Wow! Nuverian, your source is extremely readable, and incredibly extensible. I'm kind of in awe, and have built on your dialogue system with one tailored exactly to my needs in a minimal amount of time. I have a couple usability thoughts:

    1) The canvas doesn't expand when a node floats off the left side. Not a big deal, I guess, but kind of annoying for trees that tend to expand out like a pyramid.
    2) I think it would be awesome to have a Connection "parking place." What if I want to connect a node to another one that's off screen? I could drag the connection to this parking place, where its originator is "saved," scroll across my canvas, then drag the reference stored in the parking place to my destination node.
     
    Last edited: Jun 27, 2014
  46. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Well, these 2 are just different things. This solution is to just set a blackboard variable. It's not about using a blackboard variable within a Task. Both are valid of course :)
    By the way, global blackboards are definetely accessible from code. In fact any blackboard is accessible from code using the static Blackboard.Find(string blackboardName) to get it, but yeah the global variables are especialy usefull in editor.

    I really don't see a reason for FSM to have mutating features like the switcher, since FSM are in essence exactly that. You just switch from one state to the other :)

    Hey,

    Thanks a lot Marble!
    Indeed it's quite easy to create custom nodes and generaly expand the system as a whole and twist it to your needs. It was build with extensibility and modularity in mind from the ground up. I hope I somewhat succeeded then :)

    1. Indeed the canvas not expanding/showing scrollbar on left and top is something that I'm not very fancy of as well and would like to change it soon enough. There was a kind of bad initial design decision about the canvas GUI, but nothing that can't be fixed though.
    2. Indeed that might be an issue in nodes THAT far apart. Didn't happen to me yet, but could very well happen, especialy in a dialogue tree. How about right clicking on an empty port a context menu apears like "Start Connection" and then right clicking on a node and if a connection has started, the menu including "End Connection" apears? This will also save up the extra GUI parking space ;)
     
  47. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    Yep, sounds good.
     
  48. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Nice. Then it will be done :)


    For anyone that have missed it, the documentation has much changed. Here is the link:
    http://nodecanvas.com/documentation/

    Some new pages will be added as soon as the new version goes live as well.
     
  49. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Hi nuverian!


    Here we go with another JS question. I need to set an existing BB variable some value inside of a custom action.

    My reference form your scripts is as follows:

    public BBVector valueA = new BBVector{blackboardOnly = true};

    Obviosly in C#, My noob logic forced me to put this:

    public var valueA: BBVector = new BBVector(blackboardOnly = true);

    but of course it isn't right.

    Please, tell me how is the right speeling!


    Thanks!
     
  50. nuverian

    nuverian

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

    I am bit confused here :) The example you've posted is about initializing the BBVariable to be possible to read only from the blackboard and doesn't really have to do with setting it's variable value per se, meaning the vector3 value.
    If you wanted to set the variable value you simply do that OnExecute, OnUpdate or anywhere else by valueA.value = Vector3.zero for example.

    If you indeed want to initialize the variable as to read from the blackboard only as in your example, then that way of initialization is unfortunately not available in JS. The only think that you actually miss though is the ability to initialize the BBVariable as to use blackboard only (as per example) or to provide a default starting value.

    Is that what you want or I misunderstood the question?

    If yes the way around for JS for giving a default starting value would be:
    Code (JavaScript):
    1. override function Reset(){
    2.     super.Reset();
    3.     valueA.value = 2;
    4. }