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
    That was fast :)
    The new version is now live.

    Cheers!
     
  2. Async0x42

    Async0x42

    Joined:
    Mar 3, 2015
    Posts:
    104
  3. Vectrex

    Vectrex

    Joined:
    Oct 31, 2009
    Posts:
    267
    I hate to come back to this, but I'm still wondering how best to do something on exit. This seems to be a core thing in state machines. eg I have a 'Main menu' state, which on enter simply turns on the UI GO. Coming off this I have about 5 other states for things like Options, Shop, Playing game, etc.
    So how would you turn off the Main Menu GO? If I start putting a GO disable action in every single destination state, things become really messy really fast. Which then means I have to turn every GO off in every possible combination.
    The 'OnStop' override doesn't happen on transitioning out and there's no 'OnExit'. I know you don't like the idea of a separate section for exiting actions or an 'OnExit' override because of timed code running, but I think it's fine to leave it up to the user to realise it should end in one frame, or if it's a timed thing it should End properly and delay the transition.
     
  4. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey thanks,
    I am not sure how Blend Modes needs an integration though :) I mean it's basicaly setup-ed in the editor as far as I can tell.
    Correct me if I am wrong.

    Hey Cameron,

    The way to do this is to not call EndAction. OnStop will then be called when the state exits.
    OnStop is called only once, either when you manualy EndAction or when it's forced ended (eg state exits).
    For example:
    Code (CSharp):
    1. using NodeCanvas.Framework;
    2. using ParadoxNotion.Design;
    3. using UnityEngine;
    4.  
    5. public class TestAction : ActionTask{
    6.  
    7.     public GameObject go;
    8.  
    9.     protected override void OnExecute(){
    10.         go.SetActive(true);
    11.     }
    12.  
    13.     protected override void OnStop(){
    14.         go.SetActive(false);
    15.     }
    16. }
    If this looks convoluted, I can add an OnExit or similar virtual method :)

    Let me know
    Cheers.
     
  5. Async0x42

    Async0x42

    Joined:
    Mar 3, 2015
    Posts:
    104
    Maybe an integration for a small component like that is overkill, it's only a few lines of code after all :eek: I've been using Blend Modes via code for death effects on enemies, but normal use is probably through the editor GUI like you said.

    Here's the NodeCanvas integration I threw together:

    Code (CSharp):
    1. using NodeCanvas.Framework;
    2. using ParadoxNotion.Design;
    3.  
    4. using BlendModes;
    5. using RenderMode = BlendModes.RenderMode;
    6.  
    7. namespace NodeCanvas.Tasks.BlendModes
    8. {
    9.     [Category("BlendModes")]
    10.     [Name("Add or Modify a Blend Mode")]
    11.     [Description("Adds (if none exists) or modifies a blend mode effect on a gameobject")]
    12.     public class AddOrModifyBlendMode : ActionTask
    13.     {
    14.         [RequiredField] public BBParameter<BlendMode> blendMode = BlendMode.Normal;
    15.         [RequiredField] public BBParameter<RenderMode> renderMode = RenderMode.Grab;
    16.  
    17.         protected override string info
    18.         {
    19.             get { return "Add/Modify Blend Mode: " + blendMode + " (" + renderMode + ")"; }
    20.         }
    21.  
    22.         protected override void OnExecute()
    23.         {
    24.             var component = agent.gameObject.GetComponent<BlendModeEffect>();
    25.  
    26.             if (component == null)
    27.                 component = agent.gameObject.AddComponent<BlendModeEffect>();
    28.  
    29.             component.BlendMode = blendMode.value;
    30.             component.RenderMode = renderMode.value;
    31.  
    32.             EndAction();
    33.         }
    34.     }
    35. }
     
    nuverian likes this.
  6. Vallarfax

    Vallarfax

    Joined:
    Jun 13, 2015
    Posts:
    4
    Is there a way to have a custom ActionTask update on FixedUpdate? There are physics actions that I want to perform, but I don't see a good way to go about that currently.
     
  7. Danirey

    Danirey

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

    @nuverian, i have a little issue with a nested BT. If i add an interrupt or a conditional checking a bool using Check field because that value is in a external script... All BT's whith that Check crash and i can acces to them from the FSM owner. I have to remove the check editting the BT in the editor. The same check used to move from one state to another in the FSM works fine... :( Any advice?

    Cheers!
     
  8. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,
    There is no FixedUpdate right now. I will make sure to add this in the next version though.
    Thanks!

    Hey Danirey,
    I am not sure I understand the problem you are facing here. Can you post, or better sent me an example?
    Also what do you mean by crash exactly?

    Thanks.
     
  9. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Sure sorry!

    Here is a video showing the problem. The project is too big, so while you check this video, i'll try to recreate the problem in a blank project.



    In the video you can see a check field for an OverUI bool of an external script. I use it in the transition between states of the FSM and it works as supossed. When i add the same check field in the BT, it doesn't alow further edits... and hides all info about the BT and the blackboard.

    To remove it i have to edit the BT otside the FSM.

    Sorry for the confusion...:p

    Cheers!
     
  10. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Ah thanks for the video and information :) It's a bug. Here is the fix:
    Please open up Graph.cs and replace line #660 with the following:
    Code (CSharp):
    1. bbParams.Add( typeof(Task).RTGetField("overrideAgent", true).GetValue(task) as BBParameter );
    Thanks!
     
  11. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Thanks to you man!

    Great!
     
  12. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    187
    Another question: how to make a blackboard binding for a property that is defined in parent class? It does not show up in possible bindings list even tho parent's property is public.
     
  13. Vallarfax

    Vallarfax

    Joined:
    Jun 13, 2015
    Posts:
    4
    Thank you so much!
     
  14. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    @nuverian, just a reminder that the [TextAreaField(float)] attribute still doesn't wrap in the node inspector.
     
  15. Danirey

    Danirey

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

    I'm her with another question.. :p

    I've two custom tasks in my project that are reset to null each time i close Unity and open it again. All other variables still there on each task.

    Here is the set cursor task :
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParadoxNotion.Design;
    4. using NodeCanvas.Framework;
    5. using UnityEngine.UI;
    6.  
    7.  
    8. [Category("Jagged")]
    9.  
    10. public class CURSOR : ActionTask
    11. {
    12.         public bool setcursor = false;
    13.         public UI_DATA_FILLER uidata;
    14.         private Image icon;
    15.         public Texture2D cursorImage;
    16.         public Texture2D pickImage;
    17.         public Texture2D aimImage;
    18.         public Texture2D errorImage;
    19.         public Texture2D uiImage;
    20.         public LayerMask ignoreLayer;
    21.        
    22.        
    23.         protected override void OnExecute ()
    24.         {
    25. ;
    26.                
    27.         }
    28.        
    29.         protected override void OnUpdate ()
    30.         {
    31.                 if (setcursor) {//if you want only to show an especific cursor, or choose between objects
    32.                         updateCursor (null);
    33.                 } else {
    34.                         RaycastHit hit;
    35.                         Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    36.                         if (Physics.Raycast (ray, out hit, Mathf.Infinity, ignoreLayer)) {
    37.                                 updateCursor (hit.collider);
    38.                         }
    39.                 }
    40.  
    41.         }
    42.        
    43.         void updateCursor (Collider obTag)
    44.         {
    45.                 if (setcursor) {//Set only the specified first cursor
    46.                         Cursor.SetCursor(cursorImage, new Vector2(0,0), CursorMode.Auto);
    47.                 } else {//Show the cursor based on object tag
    48.                         if(uidata.OverUI){      
    49.                                 Cursor.SetCursor(uiImage, new Vector2(0,0), CursorMode.Auto);
    50.                         }else if (obTag.tag == "GROUND" || obTag.transform.root.tag == "Player") {
    51.                                 Cursor.SetCursor(cursorImage, new Vector2(0,0), CursorMode.Auto);
    52.                         } else if (obTag.tag == "Item") {
    53.                                 Cursor.SetCursor(pickImage, new Vector2(pickImage.height/2f,pickImage.width/2f), CursorMode.Auto);
    54.                         } else if (obTag.transform.root.tag == "Enemy") {
    55.                                 Cursor.SetCursor(aimImage, new Vector2(aimImage.height/2f,pickImage.width/2f), CursorMode.Auto);
    56.                         } else {
    57.                                 Cursor.SetCursor(errorImage, new Vector2(errorImage.height/2f,errorImage.width/2f), CursorMode.Auto);
    58.                         }
    59.                 }
    60.         }
    61. }
    62.  
    And here is the show path task:
    Code (CSharp):
    1. public class SHOWPATH : ActionTask
    2. {
    3.         public GameObject indicator;
    4.         public int moveCost=2;
    5.         public Material lineMaterial;
    6.         public float lineWidth;
    7.         public Texture2D frontCap;
    8.         public Texture2D endCap;
    9.         public float heightOffset = 0.1f;
    10.         private Vector3 destination;
    11.         private VectorLine myLine;
    12.         public LayerMask allowLayers;
    13.         private RaycastHit hit;
    14.        
    15.         protected override void OnExecute(){
    16.        
    17.         VectorLine.SetEndCap ("RoundedEnd", EndCap.Back,lineMaterial, 0.0f,frontCap);          
    18.         myLine = new VectorLine ("Spline", new Vector3[100 + 1], lineMaterial, lineWidth, LineType.Continuous, Joins.Fill);
    19.         myLine.endCap = "RoundedEnd";          
    20.         myLine.textureScale = 1;  
    21.         myLine.active = false;
    22.         indicator.SetActive( false);//If it is disabled, then enables it
    23.        
    24.        
    25.     }
    26.    
    27.     protected override void OnUpdate(){
    28.         if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, Mathf.Infinity, allowLayers)) {
    29.             if (hit.collider.CompareTag ("GROUND")) {
    30.                 destination = hit.point;
    31.                 drawPath ();
    32.             } else {
    33.                 myLine.active = false;
    34.                 indicator.SetActive( false);//If it is disabled, then enables it
    35.             }
    36.         }
    37.  
    38.         }
    39.        
    40.         void drawPath ()
    41.         {
    42.                 if (!agent.GetComponent<NavMeshAgent> ())
    43.                         return;
    44.                 NavMeshHit navHit = new NavMeshHit ();
    45.                 NavMesh.SamplePosition (destination, out navHit, 2f, 1);
    46.                 Vector3 tempdestination = navHit.position;  
    47.                 NavMeshPath path = new NavMeshPath ();
    48.                 agent.GetComponent<NavMeshAgent> ().CalculatePath (tempdestination, path);
    49.                 Vector3[] tempPoints = path.corners;
    50.  
    51.  
    52.                 //show the distance and AP cost
    53.                 indicator.SetActive( true);//If it is disabled, then enables it
    54.                 float distance = 0f;
    55.                 Vector3 previouspoint=agent.transform.position;
    56.                 foreach(Vector3 p in path.corners){
    57.                     distance+=Vector3.Distance (previouspoint,p);//hold the distance between all points
    58.                     previouspoint=p;
    59.                 }
    60.                 float tempAPCost = 0f;
    61.                 if(agent.GetComponent<PLAYER> ().run)//get the AP cost of the movement to that distance
    62.                     tempAPCost = Mathf.FloorToInt (distance) * (moveCost/2);
    63.                 else
    64.                     tempAPCost = Mathf.FloorToInt (distance) * moveCost;
    65.                 indicator.GetComponentInChildren<Text>().text=System.Math.Round(distance,1).ToString() + " m\n" + tempAPCost + " AP's";//send the info to the display
    66.  
    67.  
    68.  
    69.                 //continue with the path display
    70.                 for (int i = 0; i < tempPoints.Length; i++) {
    71.                     tempPoints[i] += new Vector3 (0f, heightOffset, 0f);//up a little the points over the floor
    72.                 }
    73.                 if (tempPoints.Length > 1) {                      
    74.                         if (tempPoints.Length == 2)//if it is a straight line, set the last waypoint of the line to the same height of the origin to avoid cross through slopes
    75.                                 tempPoints [1] = new Vector3 (tempPoints [1].x, tempPoints [0].y, tempPoints [1].z);
    76.  
    77.                         myLine.active = true;
    78.                         myLine.MakeSpline (tempPoints, 100, false);
    79.                         myLine.Draw3D ();
    80.                 }  
    81.         }
    82.        
    83.         protected override void OnStop ()
    84.         {
    85.             VectorLine.Destroy (ref myLine);
    86.             indicator.SetActive( false);
    87.         }
    88. }
    In the second script, the reseted variable is "indicator", which is a GameObject type. In the first script, the variable is "uidata" which is UI_DATA_FILLER type. I'm missing something? Keep in mind that all other variables are filled at edit time, and they still there after restart unity...

    Thanks a lot :)
     
  16. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Sorry I forgot that :)
    I've PMed you a way to add this now.

    Thanks!

    Hey,

    I am going to presume that the graph containing these actions, is an asset file and not a bound graph.
    If that is so, then as usual, asset can't have references to scene objects and that is why the references do not persist and are lost.

    The way to work with this would be to instead directly reference the 'indicator' GameObject, you would create a GameObject Blackboard Variable for the "indicator" and have the action use that variable.
    Since Blackboard is a component on your agent/owner, as far as the owner gameobject is in the scene this will work fine.

    For this, you would need to change the field from being a GameObject type to a BBParameter<GameObject> and you can do the same for any type you like. For example:
    Code (CSharp):
    1. public BBParameter<GameObject> indicator;
    2. public BBParameter<UI_DATA_FILLER> uidata;
    As a reminder, you can quickly create a Variable of the type required with the small "+" button highlighted in the image:
    BBParam.png

    Let me know if the problem is indeed that the graph is an asset file in the first place though :)

    Cheers!
     
  17. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Thanks man,

    I'll try later today. I knew this had something to do with the asset/bind thing… But why this is not happening with the other variables on the script? Maybe only affects to the variable that you will use between nodes?(i.e. accessing a script attached to the variable content with set field?) But with the indicator game object, i just set it active or inactive inside the the task script… So this should be happening to the other vars as well….:confused:o_O

    Anyway, i'll try and see if that solves the problem. I'll let you know.


    Thanks from spain! :cool:
     
  18. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Hey,

    I'm building for iOS a project created a few months ago with NoveCanvas 1.6.1. It was compiling fine for PC and Android, but now it shows 49 errors like this:

    ===============================================
    TargetParameterCountException: parameters do not match signature
    System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:188)
    System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MethodBase.cs:115)
    NodeCanvas.Conditions.CheckFunction.OnCheck () (at Assets/NodeCanvas/Tasks/Conditions/ScriptControl/CheckFunction.cs:77)
    NodeCanvas.ConditionTask.CheckCondition (UnityEngine.Component agent, NodeCanvas.Blackboard blackboard) (at Assets/NodeCanvas/Core/Tasks/ConditionTask.cs:44)
    NodeCanvas.ConditionalConnection.CheckCondition (UnityEngine.Component agent, NodeCanvas.Blackboard blackboard) (at Assets/NodeCanvas/Core/Graph/ConditionalConnection.cs:52)
    NodeCanvas.StateMachines.FSMState.CheckTransitions () (at Assets/NodeCanvas/Systems/FSM/FSMState.cs:106)
    NodeCanvas.StateMachines.FSMState.OnUpdate () (at Assets/NodeCanvas/Systems/FSM/FSMState.cs:92)
    NodeCanvas.StateMachines.FSM.OnGraphUpdate () (at Assets/NodeCanvas/Systems/FSM/FSM.cs:65)
    NodeCanvas.MonoManager.Update () (at Assets/NodeCanvas/Core/Other/MonoManager.cs:58)

    =================================================

    Does this mean I have to upgrade to the latest NodeCanvas? If so, is there any way to do that without manually re-creating the FSM?

    Thanks.
     
  19. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    Updating 1.x to 2.x without losing graphs is not possible, but you don't have to update for your current project.
    I am providing support for 1.x as well :)

    Can you please let me know, what has changed since the last time you compiled the project?
    As it seems though, you have some Script Control tasks that are trying to call a function which has changed parameters since the last time you used the project. Can you please confirm that this is the case?

    Let me know.
    Thanks.
     
  20. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    The only thing that I changed is the build platform (from Android to iOS). I thought that the errors may have been due to some bug that was fixed in 2.x, but it would be great if we could get it working in 1.6. Thanks!
     
  21. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    I just found the bug in CheckFunction of version 1.6. I've PMed you the fix. Let me know if everything works fine after this.

    Cheers!
     
  22. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Yes, it works fine now. Thanks for fixing this so unbelievably fast!
     
  23. Dbone

    Dbone

    Joined:
    Mar 10, 2014
    Posts:
    56
    Hi Nuverian,

    I imported NC into a new, fresh Unity 5.1 project and got this error:

    Assets/NodeCanvas/Tasks/Conditions/UGUI/ButtonClicked.cs(22,50): error CS1061: Type `Button' does not contain a definition for `onClick' and no extension method `onClick' of type `Button' could be found (are you missing a using directive or an assembly reference?)

    any ideas? It's a new project but there are a few other assets in it already.

    Windows 7 64
    Unity 5.1
    Nodecanvas 2.3.5
     
  24. nuverian

    nuverian

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

    Hm..there is probably some other asset with a name Button and thus a namespace conflict. Can you please replace the ButtonClicked.cs contents with the following and let me know.
    Code (CSharp):
    1. using NodeCanvas.Framework;
    2. using ParadoxNotion.Design;
    3. using UnityEngine.UI;
    4. using UnityEngine;
    5.  
    6. namespace NodeCanvas.Tasks.Conditions{
    7.  
    8.     [Category("UGUI")]
    9.     public class ButtonClicked : ConditionTask {
    10.  
    11.         [RequiredField]
    12.         public BBParameter<UnityEngine.UI.Button> button;
    13.  
    14.         protected override string info{
    15.             get {return string.Format("Button {0} Clicked", button.ToString());}
    16.         }
    17.  
    18.         protected override string OnInit(){
    19.             button.value.onClick.AddListener(OnClick);
    20.             return null;
    21.         }
    22.  
    23.         protected override bool OnCheck(){ return false; }
    24.         void OnClick(){ YieldReturn(true); }
    25.     }
    26. }
    Thanks
     
  25. Dbone

    Dbone

    Joined:
    Mar 10, 2014
    Posts:
    56
    I took your advice, rebuilt the project and found the source of the namespace conflict. There were a few other problems with that asset too so I've contacted the author to hopefully sort it out. In the meantime, everything is running smoothly again, thank you.
     
  26. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Thanks for letting me know :)
    Cheers!
     
  27. Async0x42

    Async0x42

    Joined:
    Mar 3, 2015
    Posts:
    104
    Love/Hate integration would be a good integration to add I think, it'd fit in with NodeCanvas as well as the Dialogue module you have
     
  28. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    hopeful likes this.
  29. Async0x42

    Async0x42

    Joined:
    Mar 3, 2015
    Posts:
    104
    That was fast, thanks!
     
  30. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    A new version has been submited to the asset store.

    Apart from a minor fix for Unity 5.1 warnings, there is a new feature that I got a request adding.
    That is the ability to run an Action List independant of any type of graph, through a new Action List Component. You basicaly add "ActionListPlayer" to a game object, add any ActionTask you like and finaly call Play() at any time to run the action list. Of course any existing or custom ActionTask can be used with this.

    ActionList.png

    At first I though of creating this as an extension, but after all it was just a bunch of lines of code, so it's included in the package. :)

    @Async0x42 you are welcome :)
     
    Async0x42 and hopeful like this.
  31. Evgeny-Eliseev

    Evgeny-Eliseev

    Joined:
    Jan 21, 2015
    Posts:
    19
    Hello!

    How to start DialogueTree from FSM?
    I created standard action Start Dialogue Tree but I can't choose DialogueTree for running (drag'n'drop and choosing from menu doesn't work).

    NodeCanvas 2.3.5 / Unity 5.1
     
  32. nuverian

    nuverian

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

    Please drag and drop the DialogueTree component directly instead of it's gameobject. It's a known issue with drag'n'dropping DialogueTrees due to the way they work.

    Let me know.
    Cheers.
     
  33. Evgeny-Eliseev

    Evgeny-Eliseev

    Joined:
    Jan 21, 2015
    Posts:
    19
    Thank you!
     
  34. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    You are welcome :)
    Cheers!
     
  35. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    The new version is now live on the asset store.

    Cheers and have fun!
     
  36. Disastercake

    Disastercake

    Joined:
    Apr 7, 2012
    Posts:
    317
    Hey nuverian,

    First off I'd like to say I'm loving NodeCanvas and it really helps me visualize and modulate my AI code. It's saved a lot of time and headaches! I have a couple suggestions that I think would benefit the UX experience:

    Is there a way to turn off the automatic priority sorting that is based on the horizontal axis? Sometimes I want to arrange by nodes in different ways, but then the nodes automatically rewire themselves to change the priority. It'd be great if there was an option to turn this off.

    Also, is it possible for the viewport to center on the nodes when opening a tree? My trees have apparently gotten offset from each other in each file, so scrolling to them is a pain when switching between graphs.
     
    Last edited: Jun 30, 2015
  37. nuverian

    nuverian

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

    Thanks! I am very glad you enjoy NodeCanvas :)

    I could really easily add an option to not sort the nodes based on their horizontal position, but the reason I haven't is that I really think that this kind of enforces a better behaviour tree structuring when making your trees, so that node priorities simply follow the order of the nodes horizontaly.
    You can change the code to try this out if you want. Simply open BehaviourTree.cs and change line #40 property to return false. If you still find it usefull, I could add an option :)

    Regarding centering the graph, the translation of the graph is normaly saved, but there seems to be some minor issue which I am actualy hunting. Meanwhile and as a reminder, you can press the "F" key to focus the graph to it's nodes in case they are not.

    Cheers!
     
  38. Vallarfax

    Vallarfax

    Joined:
    Jun 13, 2015
    Posts:
    4
    While waiting for the ability to make custom ActionTasks work with FixedUpdate, is there any sort of hack that you could recommend? I also looked into doing a custom FSMState but didn't see a way to handle things in a FixedUpdate there either. I've been working around it but the workarounds I've come up with are getting pretty gross.

    Thanks!
     
  39. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,
    I will make sure to add FixedUpdate in the next version. Meanwhile, the easiest way to add it right now would be this:
    1) Open up MonoManager.cs and add this code:
    Code (CSharp):
    1.         public event System.Action onFixedUpdate;
    2.  
    3.         void FixedUpdate(){
    4.             if (onFixedUpdate != null)
    5.                 onFixedUpdate();
    6.         }
    MonoManager is also from where everything gets it's normal update.

    2) Create your action like this:
    Code (CSharp):
    1. using NodeCanvas.Framework;
    2. using ParadoxNotion.Design;
    3. using ParadoxNotion.Services;
    4.  
    5. public class ExampleAction: ActionTask{
    6.  
    7.     protected override void OnExecute(){
    8.         MonoManager.current.onFixedUpdate += this.OnFixedUpdate;
    9.     }
    10.  
    11.     protected override void OnStop(){
    12.         MonoManager.current.onFixedUpdate -= this.OnFixedUpdate;
    13.     }
    14.  
    15.     void OnFixedUpdate(){
    16.         //do stuff :)
    17.         //EndAction(true or false);
    18.     }
    19. }
    Cheers!
     
  40. Vallarfax

    Vallarfax

    Joined:
    Jun 13, 2015
    Posts:
    4
    Thank you so much!
     
  41. noania

    noania

    Joined:
    Apr 19, 2014
    Posts:
    33
    Can you simply double click or click some icon on the "call/invoke method" node to open the script(in Monodevelop or other editor) of the method YOU ARE CALLING(not the script of node action itself)?
    What drives me crazy in other visual scripting extensions is that I have to go through extra 2-3 steps to open the script I'm looking for(searching the gameobject in hierarchy, scrolling down to the script then double clicking the script name) .
     
  42. nuverian

    nuverian

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

    This is not possible now, but I will take this as a request and add this feature in the next version :)
    Probably with the added ability to open the script at the correct line of the method/property/field declaration.

    Cheers!
     
  43. bali33

    bali33

    Joined:
    Aug 14, 2011
    Posts:
    232
    Great to see the Action List Player feature !
     
  44. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    I rarely drop feature requests :)
    Cheers!
     
  45. Async0x42

    Async0x42

    Joined:
    Mar 3, 2015
    Posts:
    104
    Just wanted to say thanks for the updates, totally appreciated and in use!
     
  46. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,
    You are welcome! :)
     
    Marble likes this.
  47. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    What is an elegant way to pass data between 2 tasks? I am using Dynamic Variables to handle this, but during runtime there will be many unused variables on the blackboard. I have to manually destroy them by directly access variable Dictionary in the blackboard.
     
  48. Prophet6989

    Prophet6989

    Joined:
    Jul 8, 2012
    Posts:
    37
    Hello!
    I create GlobalBlackboard with references to scene objects and FSM. When I place FSM on other scene, where I created GlobalBlackboard with same name, some variables links on task is broken.

    And error on this task happens at runtime. BUT if I REcreate this task, I can select same variable (“Global/World”) with drop-dowb menu.
     
  49. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,
    The way to pass data is indeed done by using Blackboard variables, either dynamic or not. Why would you want to delete the dynamic variables created in runtime though? Is this only for organization reasons? It would not be efficient to delete them since in the next loop they might just be created again.
    I could make dynamic variables created to not show in the blackboard, but that would make them impossible to visualy debug in runtime.

    Let me know if you have another suggestion in mind.
    Cheers.


    Hey,

    Hm. That's weird. I just did the following to try this:
    • I created an FSMOwner with a Bound FSM.
    • Created a Global blackboard with some variables and linked those within the owner's FSM.
    • Made the FSMOwner a prefab.
    • Created a new scene, added a Global Blackboard and created the same variables as before.
    • Added the FSMOwner prefab in the scene.

    The parameter links were there and not "broken".
    Can you please provide a step reproduction if possible?

    Thanks!
     
  50. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    I've encountered what might be a bug. Can you confirm?

    I've extended ConditionTask like so:

    Code (CSharp):
    1. namespace NodeCanvas.Tasks.Conditions {
    2.  
    3.     [EventReceiver("OnCustomEvent")]
    4.     public class MyCustomCondition : ConditionTask<GraphOwner> {
    5.  
    6.         protected override bool OnCheck() { return false; }
    7.  
    8.         public void OnCustomEvent( EventData receivedEvent ) {
    9.                 Debug.Log("Received event on " + agent.name);
    10.  
    11.                 YieldReturn( true );
    12.         }
    13.     }
    14. }
    I have a FSM with a transition. The transition has a ConditionList. When the list has only one MyCustomCondition in the list, it fires correctly. I receive the debug log when I send the graph an event.

    However, when I have two MyCustomConditions on the transition and I fire the event, only one debug log is fired. If I send another event, both debug logs go off. Both logs are reported for each subsequent event.

    My use case:

    I'm building a FSM that uses custom events to trigger state transitions. On some of those transitions, I would like to evaluate the event with several different conditions. I need the first event fired at a graph to be evaluated by all conditions in a ConditionList.