Search Unity

Behavior Designer - Behavior Trees for Everyone

Discussion in 'Assets and Asset Store' started by opsive, Feb 10, 2014.

  1. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    @Mitch -

    You're doing everything correctly, there was a bug in the priority selector task. Task a look at this post for a fix: http://forum.unity3d.com/threads/22...eryone/page9?p=1556648&viewfull=1#post1556648

    @unicoea -

    Can you post the full stack dump for the uScript KeyNotFoundException? When I know what line that is at I should be able to simply ignore the second call to end the uScript graph.

    I have a fix for the ArgumentOutOfRangeException -

    In BehaviorManager:tick, change line 455 from
    Code (csharp):
    1.  
    2. if (behaviorTree.taskList[interruptedTask] == behaviorTree.taskList[behaviorTree.activeStack[j].Peek()]) {
    3.  
    to
    Code (csharp):
    1.  
    2. if (j < behaviorTree.activeStack.Count  behaviorTree.taskList[interruptedTask] == behaviorTree.taskList[behaviorTree.activeStack[j].Peek()]) {
    3.  
    I've also made a unit test to prevent this error from happening again.
     
    Last edited: Mar 26, 2014
  2. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    57
    KeyNotFoundException: The given key was not present in the dictionary.
    System.Collections.Generic.Dictionary`2[BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree,System.Object].get_Item (BehaviorDesigner.Runtime.BehaviorTree key) (at /Applications/buildAgent/work/b59ae78cff80e584/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:150)
    BehaviorDesigner.Runtime.BehaviorManager.interrupt (BehaviorDesigner.Runtime.Behavior behavior, BehaviorDesigner.Runtime.Tasks.Task task) (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:783)
    BehaviorDesigner.Runtime.Tasks.Interrupt.interrupt (TaskStatus status) (at Assets/Behavior Designer/Runtime/Decorators/Interrupt.cs:33)
    BehaviorDesigner.Runtime.Tasks.PerformInterruption.OnUpdate () (at Assets/Behavior Designer/Runtime/Actions/PerformInterruption.cs:19)
    BehaviorDesigner.Runtime.BehaviorManager.runTask (BehaviorDesigner.Runtime.BehaviorTree behaviorTree, Int32 taskIndex, Int32 stackIndex, TaskStatus previousStatus) (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:548)
    BehaviorDesigner.Runtime.BehaviorManager.runTask (BehaviorDesigner.Runtime.BehaviorTree behaviorTree, Int32 taskIndex, Int32 stackIndex, TaskStatus previousStatus) (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:533)
    BehaviorDesigner.Runtime.BehaviorManager.tick () (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:468)
    BehaviorDesigner.Runtime.BehaviorManager.Update () (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:420)

    It happens here:
    BehaviorManager.cs line783
    $111.jpg
     
  3. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    Awesome, try this fix:

    Located about 10 lines above where your screenshot starts, change

    Code (csharp):
    1.  
    2. // stop PlayMaker/uScript if they are running
    3. if (treeObjectMap.ContainsKey(behaviorTree)) {
    4.  
    to
    Code (csharp):
    1.  
    2. // stop PlayMaker/uScript if they are running
    3. if (treeObjectMap.ContainsKey(behaviorTree)  objectTreeMap.ContainsKey(treeObjectMap[behaviorTree])) {
    4.  
    This way it should ignore the second end uScript signal call. I didn't actually test it out but it should prevent that KeyNotFoundException from occurring.
     
  4. Silly_Rollo

    Silly_Rollo

    Joined:
    Dec 21, 2012
    Posts:
    486
    I'm finally getting down to integrating this asset into my main project and with source access in the latest release this is really easy. Thanks again for choosing to do that by default!
     
  5. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    No problem, I have to admit that it does make fixing these one line bugs a lot easier :)

    Hopefully the source version will be available on the Asset Store soon. I submitted version 1.1 about 1.5 weeks ago and then this past weekend I decided to submit version 1.1.1 to get the source code version out there sooner than it otherwise would have been. I am still trying to decide if that was a good decision but there's no going back now. I promise I won't submit version 1.1.2 until 1.1.1 has been approved.
     
    Last edited: Mar 27, 2014
  6. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    57
    I tried use "if (treeObjectMap.ContainsKey(behaviorTree) objectTreeMap.ContainsKey(treeObjectMap[behaviorTree])) {"
    but error is still strange:

    KeyNotFoundException: The given key was not present in the dictionary.
    System.Collections.Generic.Dictionary`2[BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree,System.Object].get_Item (BehaviorDesigner.Runtime.BehaviorTree key) (at /Applications/buildAgent/work/b59ae78cff80e584/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:150)
    BehaviorDesigner.Runtime.BehaviorManager.interrupt (BehaviorDesigner.Runtime.Behavior behavior, BehaviorDesigner.Runtime.Tasks.Task task) (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:784)
    BehaviorDesigner.Runtime.Tasks.Interrupt.interrupt (TaskStatus status) (at Assets/Behavior Designer/Runtime/Decorators/Interrupt.cs:33)
    BehaviorDesigner.Runtime.Tasks.PerformInterruption.OnUpdate () (at Assets/Behavior Designer/Runtime/Actions/PerformInterruption.cs:19)
    BehaviorDesigner.Runtime.BehaviorManager.runTask (BehaviorDesigner.Runtime.BehaviorTree behaviorTree, Int32 taskIndex, Int32 stackIndex, TaskStatus previousStatus) (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:548 )
    BehaviorDesigner.Runtime.BehaviorManager.runTask (BehaviorDesigner.Runtime.BehaviorTree behaviorTree, Int32 taskIndex, Int32 stackIndex, TaskStatus previousStatus) (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:533)
    BehaviorDesigner.Runtime.BehaviorManager.tick () (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:468 )
    BehaviorDesigner.Runtime.BehaviorManager.Update () (at Assets/Behavior Designer/Runtime/BehaviorManager.cs:420)
     

    Attached Files:

    • $ddd.jpg
      $ddd.jpg
      File size:
      75.9 KB
      Views:
      865
    Last edited: Mar 27, 2014
  7. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    57
    If i use graph above, it's fine.(any one know how to delete image post before?)
    but when use graph below, it's the same error:
    I can send you the project, if you need.
    By the way, I feel integrate uscript node function is very useful!
    Thank you to provide the integrate function! :p
    $eee.jpg
     
    Last edited: Mar 27, 2014
  8. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    57
    I found another little bug:
    First create a node in tasks( for example the BehaviourTree Reference Node),Then Click Inspector ,select the node(), drag a behavior asset from Project to external behavior slot, it will lost focus of the node.
    When you click the blackboard then select the node again,then drag asset on it, it will not lost the focus anymore.
    $a1.jpg
    $a2.jpg
    $a3.jpg
    $a4.jpg
    $a5.jpg
     
  9. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    I should have gotten you to beta test :)

    I sent you a PM asking for your project and after trying to reproduce it I am definitely going to need to take a closer look at your project. I wasn't able to reproduce the uScript issue even when I didn't include the fix that I sent yesterday. If you could PM/email me your project that would be great.

    As far as the editor loosing focus on the task, thanks, I'll send you a new version of Behavior Designer after I get this uScript issue fixed.
     
    Last edited: Mar 27, 2014
  10. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    For those playing along with the uScript issue I have a fix (thanks to unicoea for sending his project). This actually affects those using PlayMaker as well. Find this line within BehaviorManager:interrupt:

    Code (csharp):
    1.  
    2.             // stop PlayMaker/uScript if they are running
    3.             if (treeObjectMap.ContainsKey(behaviorTree)) {
    4.                 object[] objectValueArray = new object[1] { treeObjectMap[behaviorTree] };
    5.  
    And change it to:
    Code (csharp):
    1.  
    2.             // stop PlayMaker/uScript if they are running
    3.             if (treeObjectMap.ContainsKey(behaviorTree)) {
    4.                 object[] objectValueArray = new object[1] { treeObjectMap[behaviorTree] };
    5.                 // remove the mapping because the execution has stopped
    6.                 objectTreeMap.Remove(treeObjectMap[behaviorTree]);
    7.                 treeObjectMap.Remove(behaviorTree);
    8.  
    Also, remove the following that is at the end of that block of code:

    Code (csharp):
    1.  
    2.                 objectTreeMap.Remove(treeObjectMap[behaviorTree]);
    3.                 treeObjectMap.Remove(behaviorTree);
    4.  
    The changes that I mentioned a few posts ago will not fix the bug. If you don't have the source version because the Asset Store hasn't approved it yet send me an email/PM and I'll send you the latest (I am really hoping Unity approves this version before the weekend...). This change will be going into version 1.1.2.
     
  11. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    57
    yes! it's works!:)
    I have two more question in my mind:
    1. Can i stop behavior tree/ or set variables from outside the behavior tree?
    2. how to define a coroutine in action, the task.cs include coroutine support.

    Thank you!
     
  12. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    Great to hear!

    1. You can sop a behavior tree from outside of the behavior tree by calling behavior.disableBehavior(). You can also pause it by calling behavior.disableBehavior(true). You can get/set the shared variable from outside the behavior tree by calling behavior.GetVariable("name")/SetVariable("name", SharedVariable). I can see this being a popular question so I'll add it to the documentation.

    2. You should be able to start/stop a coroutine within the task just like any other MonoBehaviour object. For example:

    Code (csharp):
    1.  
    2.     public override void OnStart()
    3.     {
    4.         StartCoroutine("MyCoroutine", 3);
    5.     }
    6.  
    7.     public IEnumerator MyCoroutine(int value)
    8.     {
    9.         yield return null;
    10.  
    11.         Debug.Log("Value: " + value);
    12.     }
    13.  
     
    Last edited: Mar 28, 2014
  13. kenleeroy

    kenleeroy

    Joined:
    Mar 28, 2014
    Posts:
    1
    Love this asset so far! Is there any way to get the latest version from you before it hits the store?
     
  14. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    It's great to hear that you're enjoying it. Definitely - send me an email/PM with your invoice number and I'll send you a link with the latest.
     
  15. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    57
    Great support!
    Now i can use scripts outside connect/share variable with behavior tree.
    I am very excited about it. Thank you! :p
     
  16. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    57
    I found how to reproduce the focus one, I have send a video link through PM.
     
  17. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    57
    Hi!
    Happy to see it's getting close to more perfect! There is a small question here:
    I tried to make a action with coroutine like this, but it log error about the `IEnumerator' keyword,how can i define a coroutine?
    tks!

    using UnityEngine;
    namespace BehaviorDesigner.Runtime.Tasks
    {
    [TaskIcon("{SkinColor}LogIcon.png")]
    public class MyCoroutineTest : Action
    {
    public override void OnStart()
    {
    StartCoroutine("MyCoroutine", 3);
    }

    public IEnumerator MyCoroutine(int value)
    {
    yield return null;
    Debug.Log("Value: " + value);
    }
    }
    }

    Assets/Behavior Designer/Runtime/Actions/MyCoroutineTest.cs(13,24): error CS0246: The type or namespace name `IEnumerator' could not be found. Are you missing a using directive or an assembly reference?
     
  18. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    Make sure you are including the System.Collections namespace:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. namespace BehaviorDesigner.Runtime.Tasks
    5. {
    6.     [TaskIcon("{SkinColor}LogIcon.png")]
    7.     public class MyCoroutineTest : Action
    8.     {
    9.         public override void OnStart()
    10.         {
    11.             StartCoroutine("MyCoroutine", 3);
    12.         }
    13.  
    14.         public IEnumerator MyCoroutine(int value)
    15.         {
    16.             yield return null;
    17.             Debug.Log("Value: " + value);
    18.         }
    19.     }
    20. }
    21.  
    Thanks for sending that video on the focus issue. I have it fixed and I am just working on packaging everything up again.

    Edit: PM sent with the updated package.
     
    Last edited: Mar 29, 2014
  19. Silly_Rollo

    Silly_Rollo

    Joined:
    Dec 21, 2012
    Posts:
    486
    Is there any way to see an external behavior tree in action at run time? Alternatively, is there a way to "load" a behavior tree in the same way you can save one?
     
  20. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    Behavior Designer 1.1.1 was approved yesterday. The major features include the runtime source code as well as variables. Now, it is going to take a little bit of work in order to update. The Asset Store cannot remove files so when you first import the update you are going to get the following warnings/errors:

    $import.PNG

    Luckily these are really easy to fix. If you browse to the Behavior Designer/Editor directory you'll notice three BehaviorDesignerEditor assemblies:

    $editor.PNG

    Remove the selected assembly, BehaviorDesignerEditor - notice that this assembly does not have "pre" or "post" in its name or extension. When you delete that assembly the error should go away and you'll get the dialog to popup asking you to remove the unnecessary assembly. Go ahead and select yes to it. Once that is done you'll just get warnings about type conflicts. This is caused by now having the runtime source code included. To fix it all you need to do is delete the runtime assembly:

    $runtime.PNG

    That should take care all of the errors/warnings relating to the actual files. Now, you'll still probably receive some other warnings which relate to the data format change. I mentioned it in this post but I'll copy the steps here as well:

    --------

    The data format that the behavior trees are stored in has changed since version 1.0.3 to accommodate being about to export to an asset file. This means that when you open up Behavior Designer with an old format behavior tree you'll get the following message:

    $update.PNG

    As soon as you hit OK the following window will appear:

    $updatewindow.PNG

    Once you hit update you should never have to see either of those two messages again. You can also access this window from the Window/Behavior Designer Update Tool menu item. If for some reason you don't update and choose to run the behavior tree as it is you'll see the following messages in your console:


    I did a lot of testing to make sure no data would be lost but as with all changes there is a chance something bad can happen so make sure you have a backup of your behavior tree first. If something bad does happen please get in contact with me.


    With this update you will also see two other warning messages. The first one tells you that the shared/synchronized field has been deprecated:
    And the second one tells you that the External Behavior Tree task has been deprecated:
    That should be all of the warnings that you'll see when you update to the latest version. If you have any problems at all please let me know.
     
    Last edited: Mar 29, 2014
  21. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    As soon as I get version 1.1.2 submitted I will be working on version 1.2 and one of the main features will be able to see the external behavior trees executing. So not yet but soon. When I do implement it, it will be similar to what you are talking about in "loading" a behavior tree - basically what I plan on doing is during runtime showing the tasks that the external behavior tree contains rather than showing the behavior tree reference task.
     
  22. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    725
    @Opsive: Thanks for your help; in your next to last post you wrote "Remove the selected assembly, BehaviorDesignerEditor.dll" but in the picture just above the selected file is BehaviorDesignerEditor (no .dll at the end). So which one should we really delete? I just want to be sure. Same thing for the Runtime folder...
     
  23. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    I guess that is confusing. The project window hides extensions so I shouldn't have added the dll in my description. I just edited my post. You want to delete the one without dll.
     
  24. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    725
    Ok I believe I followed your instructions to the letter yet I still get an error:

    $2isxppl.png
     
  25. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    So the only assembly that you have from Behavior Designer is BehaviorDesignerEditor.dll, correct? Try deleting that assembly and see if you still get the error. If you do not get the error anymore then import Behavior Designer from the asset store and at that point you shouldn't get any warnings/errors. If you do still get the error even after deleting BehaviorDesignerEditor.dll then most likely an old version of that assembly is still hanging around somewhere.

    If neither of those solutions work can you send me a stripped down version of your project?
     
  26. Hazor

    Hazor

    Joined:
    Feb 5, 2013
    Posts:
    25
    I fixed that by moving folders from Assets/Plugins to just /Assets. Not sure if you are in the same boat. (i use the non assets store version)
     
  27. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    That's a good suggestion, Hazor. When I built the dll for the editor I referenced the Assembly-CSharp assembly. If you place the runtime directory in the Plugins directory then it gets loaded in the Assembly-CSharp-firstpass assembly. I'll see if I can come up with a way to remove that requirement. The only alternative may be to include two separate editor assemblies: one referencing Assembly-CSharp and one referencing Assembly-CSharp-firstpass
     
    Last edited: Mar 29, 2014
  28. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    725
    For me Behavior Designer installs by default into the Assets directory. So I tried moving the folder to the Assets/Plugins directory but it created an error so I moved it back to the Assets directory. :(
     
  29. Hazor

    Hazor

    Joined:
    Feb 5, 2013
    Posts:
    25
    No, i mean, for me Behavor designer installs on Assets too.. But i had another plugin what i was not using on Assets/Plugin directory (control Freak). After multiples tests i removed it from there (deleted as i don't need it on this project), then reimported the package and it worked.

    So, my suggestion is move the folders from other asset store Plugins from plugin folder to Assets. Not moving Behavior Designer.
     
    Last edited: Mar 29, 2014
  30. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    @Hazor

    Thanks for the info - it really helped me get started figuring out what is wrong. After a ton of debugging I am concluding that it the problem is caused by a Unity bug. When Unity compiles it should compile the runtime first followed by the editor. However, when you have the Plugins/Editor folder it will compile the editor and then the runtime. I've made a post about it here and filed a Unity bug report (case 599473). For now I managed to create a workaround so you don't have rearrange the project structure of other assets.

    I've broken up Behavior Designer into two directories: the standard /Behavior Designer directory and a /Plugins/Behavior Designer/runtime directory. The good news is that with this structure everything works as you'd expect it to. The downside is that this means yet another file change when Behavior Designer gets updated. I am going to submit version 1.1.2 this weekend and this is the last major file change that I have planned.
     
  31. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    725
    @Hazor: Thanks for clearing that up! Opsive found a solution so everything's peachy now.

    @Opsive: So I was wondering since the serialization method has changed in the new version: where are the Behavior Trees archetype stored now? I mean are they individual asset/prefab files we need to be aware of?

    My second point is about the new fading system feature on the active node/branch. It looks really nice but I was thinking that before, when the lighting up was harsh (in one frame) it was also very telling of which node was being fired up. From a practical point of view it helped me a couple of times pinpointing a very tricky one-frame node-blink. So I guess what I'm asking is would it be possible to have the fade in/out of the nodes be an option you could toggle? I hope you see what I mean...
     
  32. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    All of the tasks are now stored in the object BehaviorSource. BehaviorSource contains the bare minimum for the behavior tree to operate, which basically just includes the tasks and variables. When you are working with a behavior tree within a scene/prefab the BehaviorSource object lives within the Behavior Tree component. When you save the behavior tree out to an asset file, the BehaviorSource object lives within the External Behavior Tree component (this is the reason why I deprecated the task named "External Behavior Tree", I figured that external behavior tree name was more appropriate for a component name than a task name). So to answer your question, you don't need to be aware of any individual asset/prefab files unless you make them yourself.

    For the task fading - definitely, I'll add it now so it will be in version 1.1.2.

    Also, thanks again for all of your help in debugging the Plugins/Editor problem!
     
  33. Silly_Rollo

    Silly_Rollo

    Joined:
    Dec 21, 2012
    Posts:
    486
    Is there a way to set a shared variable on an external tree from another script?
     
  34. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    Do you want to set the value before the external tree is running or as the tree is running? In both cases for version 1.1.1 the answer is no, but I just added both cases to version 1.1.2. In version 1.1.1 you can only set a shared variable if it lives on the behavior tree component. With 1.1.2 you can set the variable on an external behavior class before it runs, as well as when the external tree gets loaded you'll see whatever variables that you've setup in that external tree show up in the parent behavior tree. For example..

    On an external behavior tree I have a task called OutputValue. All it does is output the variable value whenever it changes:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using BehaviorDesigner.Runtime;
    4. using BehaviorDesigner.Runtime.Tasks;
    5.  
    6. public class OutputValue : Action
    7. {
    8.     public SharedInt intVariable;
    9.     private int prevValue = -1;
    10.    
    11.     public override TaskStatus OnUpdate()
    12.     {
    13.         if (intVariable.Value != prevValue) {
    14.             Debug.Log("New Variable Value " + intVariable.Value);
    15.             prevValue = intVariable.Value;
    16.         }
    17.         return TaskStatus.Running;
    18.     }
    19. }
    20.  
    Now I add that task to an external behavior tree and add the variable "MyIntVariable" to that tree:

    $external behavior.PNG

    When I create the parent behavior tree it is just going to reference that external behavior tree, and notice there are no variables created:

    $parent.PNG

    When I hit play that same behavior tree will load up the variable from the behavior tree reference:

    $loaded.PNG

    I then created a regular MonoBehaviour script that will reference that behavior tree:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using BehaviorDesigner.Runtime;
    4.  
    5. public class SetValueGUI : MonoBehaviour {
    6.  
    7.     public Behavior behavior;
    8.    
    9.     public void OnGUI()
    10.     {
    11.         if (GUILayout.Button("Increase")) {
    12.             var sharedInt = (SharedInt)behavior.GetVariable("MyIntVariable");
    13.             sharedInt.Value++;
    14.         }
    15.     }
    16. }
    17.  
    When I hit the "Increase" GUI button you'll see the log output as well as the variable change within Behavior Designer:

    $value.PNG

    Is this what you are looking for? I can package this version up and send it to you.
     
    Last edited: Mar 30, 2014
  35. Hazor

    Hazor

    Joined:
    Feb 5, 2013
    Posts:
    25
    Hi Opsive

    First, i am not a programmer just a playmaker user so don't laught :D

    I am tring to make a switch getting playmaker global string variables to define a task order. My problem is what i have no idea how to manually select an output task.

    I have no idea about performance cost but, well i like the idea of a mega big tree with a clean canvas. :D

    So Is it possible to output something predefined? something like in case FSM string.Value = "Playing" select first task child? Or there is another more efficient way to do this?

    Here is the code/collage i made.

    Thanks!

    Code (csharp):
    1. using UnityEngine;
    2. using HutongGames.PlayMaker;
    3. using BehaviorDesigner.Runtime;
    4.  
    5. namespace BehaviorDesigner.Runtime.Tasks
    6.  
    7. {
    8.    
    9.     [HelpURL("")]
    10.     public class StringSwitch : Composite
    11.     {
    12.  
    13.         public FsmString CurrentStateFsmString;
    14.              
    15.  
    16.         public override void OnAwake()
    17.     {
    18.         CurrentStateFsmString = FsmVariables.GlobalVariables.GetFsmString ("Current_State");
    19.     }
    20.  
    21.         public override TaskStatus OnUpdate()
    22.         {
    23.         string clamp_cam = CurrentStateFsmString.Value;
    24.  
    25.             switch(clamp_cam)
    26.             {
    27.                 case("Idle"):
    28.                     return TaskStatus.Success;
    29.  
    30.                 case("Launch_Ball_State"):
    31.                     return TaskStatus.Success;
    32.                 default:
    33.                     return TaskStatus.Failure;
    34.             }
    35.         }
    36.  
    37.         public override void OnReset()
    38.         {
    39.  
    40.         }
    41.     }
    42. }
    43.  
     
    Last edited: Mar 30, 2014
  36. unicoea

    unicoea

    Joined:
    Feb 18, 2013
    Posts:
    57
    "The behavior tree reference" is like subTree and Template (like in playmaker or uscript), when the variable can be access by parent tree or any script outside is wonderful.
    But think about how to display them? Suppose this, if we have many reference subTrees in a parent tree graph, the variables of reference subTrees will show themselves all in menu, like variables belongs to the parent tree graph, this maybe cause confusion(can't figure out which variable belongs to which tree)
    Maybe we can show the variables of subTree only when we select the Behavior Tree Reference Node, if we click the blackboard the "variable menu" only show the variables belongs to the main parent tree graph.In the next second, i find it a bad idea,because there is an exception of this:
    If a subTree have Its own reference tree...loop like this, then the solution above still can't deal with it.

    It's seems to need to figure out how to display the variables between trees.
    May be the "variable menu" can just list variables like a tree struct. It will be very Intuitive to figure out the relations of variable of parent and child trees,see them in the same time and clearly.
     
  37. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    @Hazor

    The first thing that I would do in your situation is take a look at the PrioritySelector task since that is the most closely related composite task that you want to create.

    The part that we care about the most within that task is the CurrentChildIndex method. You can determine which child to execute next based off of the PlayMaker globals:

    Code (csharp):
    1.  
    2.         public override int CurrentChildIndex()
    3.         {
    4.             string clamp_cam = CurrentStateFsmString.Value;
    5.             int childIndex;
    6.             switch(clamp_cam)
    7.             {
    8.                 case("Idle"):
    9.                         childIndex = 1;
    10.                         break;
    11.                 case("Launch_Ball_State"):
    12.                         childIndex = 2;
    13.                         break;
    14.                 default:
    15.                         childIndex = 0;
    16.                         break;
    17.             }
    18.  
    19.             if (childIndex < children.Count) {
    20.                 return childIndex;
    21.             }
    22.             return 0;
    23.         }
    24.  
    With this code it will get the global variable string, determine which index to run based off of that string, and then return that index (first making sure the value is valid). Now, you may also need to override a few other methods depending on how you want the task to function. For example, with CanExecute you can determine when to stop executing the child tasks. Do you only want to execute each task once? Does the PlayMaker variable return a special string to you? Do you want it to execute forever and have to be interrupted? In the priority selector task we only execute each task once. For the remaining composite methods I would first take a look at the selector task and compare that to the parent task API in order to determine if you need to override it. Of course, I don't mind helping if you give me a little bit more details on how you want the task to function

    @unicoea

    You bring up some good questions. For right now I am going to submit version 1.1.2 as it is just because I don't want anybody to be in the same situation Seith was. In version 1.2 we'll come back and decide what to do to improve it (if anything).
     
  38. Silly_Rollo

    Silly_Rollo

    Joined:
    Dec 21, 2012
    Posts:
    486
    That sounds like it would work. I'm testing out using BTs for the turn actions in my turn based game. This is a rough example of what I have currently for a melee char:

    $ScreenClip[3].png

    They are all custom actions. I reversed the repeater to success so individual nodes could return failure and restart the sequence. I also defined a custom shared variable for my generic character holder class 'character'. Each time the external BT tree is invoked it needs to set the character shared variable to the currently selected character as each action needs that reference. I went ahead and edited the first task to do a GetComponent on the current gameObject but I'd prefer the neater way to setting the external tree shared variable before I enable it.

    Is this using the asset in the proper way? The final node returns success if the character is out of AP but otherwise returns failure so the whole sequence is repeated until the character has exhausted their AP and then End Turn is called. Seems to work well so far but want to break down them down into smaller nodes for better control in the future.
     
  39. AdamGoodrich

    AdamGoodrich

    Joined:
    Feb 12, 2013
    Posts:
    3,649
    Hi,
    Just purchased and added this to a project targeting windows mobile - the project now fails to compile. Is this support planned soon?
    Ta,
    Adam.
     
  40. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    @Fuzzy_Slippers -

    Yes, that looks like it would work. The alternative is to use an InheritedVariable and you could pass the character value down to the referenced behavior tree. The RTS sample project has an example of this.

    Also, it looks like your window is darker than it should be. Some other asset is messing with the color settings and not reverting it back properly. I guess I need to stop assuming that the colors will always be what they should be.

    @Adam -
    Thanks for your purchase. Yes, there is actually a fix in version 1.1.2 for Windows RT platforms. If you send me your invoice number I'll send you the new version.
     
  41. Pyromuffin

    Pyromuffin

    Joined:
    Aug 5, 2012
    Posts:
    78
    I'm seeing a bug where the tree is not highlighting as it's executing. it only happens for my particular tree, not for ones made out of the included tasks. I'll try to narrow it down to which task causes this.

    edit: i rebuilt the tree from scratch, and now it seems to be highlighting. Not really sure what the problem is.
     
    Last edited: Mar 31, 2014
  42. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    Yeah that would be great if you could narrow it down. If you even get it down to a few tasks and can send me that behavior tree that would be extremely helpful. Which version of Behavior Designer are you running?

    Edit: I just saw your edit, I think that the problem was fixed in version 1.1.2. I'll send you a PM with the link.
     
    Last edited: Mar 31, 2014
  43. Pyromuffin

    Pyromuffin

    Joined:
    Aug 5, 2012
    Posts:
    78
    excellent, thank you.

    additionally, I'm having trouble getting behavior tree reference to work at all. I get this huge error when trying to run a behavior tree reference:

    NullReferenceException: Object reference not set to an instance of an object
    BehaviorDesigner.Runtime.DeserializeJSON.DeserializeTask (BehaviorDesigner.Runtime.BehaviorSource behaviorSource, System.Collections.Generic.Dictionary`2 dict, System.Collections.Generic.Dictionary`2 IDtoTask, System.Collections.Generic.Dictionary`2 taskIDs) (at Assets/Packages/Behavior Designer/Runtime/DeserializeJSON.cs:168)
    BehaviorDesigner.Runtime.DeserializeJSON.DeserializeTask (BehaviorDesigner.Runtime.BehaviorSource behaviorSource, System.Collections.Generic.Dictionary`2 dict, System.Collections.Generic.Dictionary`2 IDtoTask, System.Collections.Generic.Dictionary`2 taskIDs) (at Assets/Packages/Behavior Designer/Runtime/DeserializeJSON.cs:262)
    BehaviorDesigner.Runtime.DeserializeJSON.DeserializeTask (BehaviorDesigner.Runtime.BehaviorSource behaviorSource, System.Collections.Generic.Dictionary`2 dict, System.Collections.Generic.Dictionary`2 IDtoTask, System.Collections.Generic.Dictionary`2 taskIDs) (at Assets/Packages/Behavior Designer/Runtime/DeserializeJSON.cs:262)
    BehaviorDesigner.Runtime.DeserializeJSON.DeserializeTask (BehaviorDesigner.Runtime.BehaviorSource behaviorSource, System.Collections.Generic.Dictionary`2 dict, System.Collections.Generic.Dictionary`2 IDtoTask, System.Collections.Generic.Dictionary`2 taskIDs) (at Assets/Packages/Behavior Designer/Runtime/DeserializeJSON.cs:262)
    BehaviorDesigner.Runtime.DeserializeJSON.Deserialize (BehaviorDesigner.Runtime.BehaviorSource behaviorSource) (at Assets/Packages/Behavior Designer/Runtime/DeserializeJSON.cs:45)
    BehaviorDesigner.Runtime.BehaviorSource.checkForJSONSerialization () (at Assets/Packages/Behavior Designer/Runtime/BehaviorSource.cs:60)
    BehaviorDesigner.Runtime.BehaviorManager.addToTaskList (BehaviorDesigner.Runtime.BehaviorTree behaviorTree, BehaviorDesigner.Runtime.Tasks.Task task, System.Boolean hasExternalBehavior, Boolean fromExternalTask, System.Collections.Generic.Dictionary`2 inheritedFields) (at Assets/Packages/Behavior Designer/Runtime/BehaviorManager.cs:251)
    BehaviorDesigner.Runtime.BehaviorManager.enableBehavior (BehaviorDesigner.Runtime.Behavior behavior) (at Assets/Packages/Behavior Designer/Runtime/BehaviorManager.cs:113)
    BehaviorDesigner.Runtime.Behavior.enableBehavior () (at Assets/Packages/Behavior Designer/Runtime/Behavior.cs:169)
    BehaviorDesigner.Runtime.Behavior.Start () (at Assets/Packages/Behavior Designer/Runtime/Behavior.cs:160)

    edit: the line is this
    fields.SetValue(task, behaviorSource.Owner.DeserializeUnityObject(Convert.ToInt32(dictValue)));

    double edit:
    now that I've cut and pasted the tree from an asset, the tree no longer highlights again.
     
    Last edited: Mar 31, 2014
  44. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    It looks like the external tree isn't keeping the reference to the Unity object. Is this happening with the version that I just sent you? Can you send me the external tree that you are trying to load? I'm not at my computer right now but I'll take a look at it when I get back in a couple of hours
     
  45. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    I am working on version 1.2 and am just finishing up with the feature that will let you view external behavior trees within the editor as they are running. For example, from the RTS example project,

    $before.PNG

    becomes

    $after.PNG

    This feature will be optional so you won't have to see a ginormous tree unless you want to. What other features would you like to see? I have a short list of new features that I know that I am going to add but I'd like to see if there is a popular feature that I am missing.
     
  46. bblumberg

    bblumberg

    Joined:
    Apr 2, 2014
    Posts:
    2
    Hi

    I have been playing around with Behavior Designer for a couple of days and am quite impressed (I was Damian Isla's thesis advisor at the Media Lab before he went to Bungie, so its fun to see how Behavior Trees have evolved in the intervening years.)

    My question is a simple one: can you build behavior trees at runtime? I am doing a prototype where part of the user interaction would be laying out a task for a robot to perform by interacting with the robot and then have the robot perform it. I'd like to use behavior trees as the execution engine if you will, and having the visual editor is a definite plus for refinement and debugging. While training the behavior tree wouldn't be active. Quickly looking at the code, it seemed like this was a possibility, but before I jump in, I wanted to verify that this was in fact the case.

    Thanks and great job.

    bb
     
  47. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    Hi bb,

    I'm really glad to hear that you are enjoying Behavior Designer so far and that means a ton coming from somebody with your creditability. That's really cool that you were Damian Isla's thesis adviser.

    For your question, you can create the individual tasks at runtime but you won't be able to use the actual Behavior Designer editor. That editor heavily relies on the UnityEditor namespace so there isn't really a way that I'd be able to get the editor to appear during runtime. To create the tasks at runtime you'd basically have to do what the editor does: instantiate the task and then parent the task. After you've created your tree of tasks you'd assign it to the BehaviorTree.RootTask object and then enable that behavior tree within the behavior manager. That said, it would take a lot of runtime code to get everything working correctly and there may be a better way.

    In version 1.1 I added the behavior tree reference task. This task contains a virtual method (getExternalBehavior) that allows you to specify where the external behavior tree is coming from. In version 1.2 I plan on making this an array so you can dynamically generate a behavior tree. I think that this would work perfect for your situation and wouldn't require you to create the tasks during runtime. What you would do is have a set of external behavior trees and then at runtime you determine which behavior tree runs depending on what tasks the user chooses. I haven't added this feature yet but I can send it to you as soon as I get done adding it (which will probably be within the next week or so).
     
    Last edited: Apr 2, 2014
  48. TheLordDave

    TheLordDave

    Joined:
    Mar 2, 2014
    Posts:
    28
    Im having an issue with a BT attached to a prefab.

    The prefab is used to generate instances at run time. Each object is instantiated with a BT and the BT runs.

    I have 2 basic tasks, a 'Find Food' Task and the 'Move Toward' task from the documentation. The problem I have is that each entity finds the correct nearest food item to their position and stores it in a shared transform. But when the game runs all of the instances then move to the same transform position. It is as if the sharedTransform is being shared accross all instances of the prefab rather than being local to each instance and being overwritten each time it is calculated for all instances.

    Any ideas what may be causing this or how to get around it?

    Thanks
     
  49. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    4,738
    It looks like those shared variables really want to be shared :)

    I have a fix for it. The trouble is, my fix is intertwined with some of the new feature work that I've been doing for version 1.2. Do you mind if I send what I have over to you instead of trying to integrate this fix in a previous version? I haven't really messed with any new runtime features in this version so if anything goes wrong it will just be in the editor.. But I've been using the editor for a different project and I haven't noticed any problems.

    You have PMs disabled so send me an email with your invoice number and I'll send you a link to the new version.
     
    Last edited: Apr 4, 2014
  50. TheLordDave

    TheLordDave

    Joined:
    Mar 2, 2014
    Posts:
    28
    Sure, I will drop you an email now.
    Thanks.
     
unityunity