Search Unity

Behavior Designer - Behavior Trees for Everyone

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

  1. Eric-Gu

    Eric-Gu

    Joined:
    Feb 19, 2014
    Posts:
    28
    Hi,Excuse me. I developed my project in the way of compiling source codes into dlls and exporting dlls into Unity project. So I compiled the runtime codes in the folder BehaviorDesigner/RunTime and Plugins/BehaviorDesigner/RunTime into dlls. Those codes were compiled successfully. I imported individual dll into the folder Scripts and Plugins.

    But It seemed that BehaviorDesignerEditor.dll in the folder BehaviorDesigner/Editor constantly tried to load assembly Assembly-CSharp-firstpass. I tried to rename the dll as Assembly-CSharp-firstpass.dll, which was compiled from the codes in the folder Plugins/BehaviorDesigner/RunTime.

    But there were some errors when run in Unity, such as'Could not load type 'BehaviorDesigner.Runtime.NodeData' from assembly 'Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.'

    Now I can use runtime part of BehaviorDesigner in the form of dll. But editor of BehaviorDesigner doesn't work due to some loading assemblies issue. How could I fix this issue? Thanks!
     
  2. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    You could use the Behavior Tree Reference task and have that point to the same external tree. That would then allow you to reuse the same tasks within multiple parts of the tree.
     
  3. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Are you using the runtime source version or the dll version? Due to the order Unity compiles the various assemblies the runtime source version has to reference the firstpass assembly in order for it to successfully compile. The non-source version does not need to reference the firstpass assembly so you could try using that.
     
  4. Eric-Gu

    Eric-Gu

    Joined:
    Feb 19, 2014
    Posts:
    28
    I am using runtime source version. I compiled source codes in the folder BehaviorDesigner/Runtime and Plugins/BehaviorDesigner/Runtime into individual dll. I imported them into the visual studio project and referenced dll properly and they worked perfectly.

    There is BehaviorDesignerEditor.dll and a few source codes in the folder BehaviorDesigner/Editor. I leave them where they are. But there is some prompt in the console of Unity Engine after I import the dll compiled from BehaviorDesigner/Runtime and Plugins/BehaviorDesigner/Runtime and I have deleted the original source codes.

    ============================================================================
    Unhandled Exception: System.Reflection.ReflectionTypeLoadException:The classes in the module cannot be loaded.

    The following assembly referenced from BehaviorDesignerEditor.dll could not be loaded:
    Assembly: Assembly-CSharp-firstpass (assemblyref_index=2)
    Version: 0.0.0.0
    Public Key: (none)

    The assembly was not found in the Global Assembly Cache, a path listed in the MONO_PATH environment variable, or in the location of the executing assembly
    ============================================================================

    It seemed that BehaviorDesignerEditor.dll in the folder BehaviorDesigner/Editor constantly tried to load assembly Assembly-CSharp-firstpass. I renamed the dll as Assembly-CSharp-firstpass.dll, which was compiled from the codes in the folder Plugins/BehaviorDesigner/RunTime. But it doesn't work either.

    How could I fix the issue concerned with BehaviorDesignerEditor.dll after I compiled the source codes in the folder BehaviorDesigner/Runtime and Plugins/BehaviorDesigner/Runtime into individual dll?

    Thanks!
     
  5. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    If you use the Asset Store version of BehaviorDesignerEditor.dll it won't try to reference the first pass assembly
     
  6. llJIMBOBll

    llJIMBOBll

    Joined:
    Aug 23, 2014
    Posts:
    578
    Hi, I'm trying to make this work with RFPS, I have the movement pack installed and rfps Intergration files. On playing the Ai is walking on the spot and I get a few errors?

    NullReferenceException: Object reference not set to an instance of an object
    BehaviorDesigner.Runtime.Tasks.Movement.Patrol.OnStart () (at Assets/Behavior Designer Movement/Scripts/Tasks/Patrol.cs:30)

    NullReferenceException: Object reference not set to an instance of an object
    BehaviorDesigner.Runtime.Tasks.Movement.Patrol.Target () (at Assets/Behavior Designer Movement/Scripts/Tasks/Patrol.cs:76)

    Does this require to use waypoints? As My Ai use wave spawner and search for player

    Thanx

    edit, It appears it disables AiAgent on scene start?
     
  7. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Just responded on the opsive forums: http://opsive.com/forum/index.php/topic,2424.0.html
     
  8. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    With the latest version of the Movement Pack make sure you set the arrive distance to a positive number so the AI knows that it has arrived at the waypoint. The RPFS AIAgent component is disabled because it would interfere with the Behavior Designer tree - you can accomplish everything within the tree that is within AIAgent so that component isn't necessary.
     
  9. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Which aspect are you referring to?
     
  10. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    The thing about behavior trees are that it's up to you to design the tree. If you don't add anything to the tree or setup a task incorrectly then it's not going to function correctly. The error that you posted dealt with not specifying any waypoints for the Patrol task. If you're new to behavior trees I highly recommend that you take a look at the following resources:

    http://www.gamasutra.com/blogs/ChrisSimpson/20140717/221339/Behavior_trees_for_AI_How_they_work.php
    http://opsive.com/assets/BehaviorDesigner/videos.php?id=13
    http://opsive.com/assets/BehaviorDesigner/videos.php?id=7
    http://opsive.com/assets/BehaviorDesigner/videos.php?id=8
    http://opsive.com/assets/BehaviorDesigner/documentation.php?id=119

    In addition, the RFPS sample project will work out of the box after you make the RFPS changes. From there it's more of how do you want to design your tree. Once you get the hang of it it'll be second nature and you won't know how to design an AI without it :)
     
    Last edited: May 20, 2016
    llJIMBOBll likes this.
  11. Steve-Tack

    Steve-Tack

    Joined:
    Mar 12, 2013
    Posts:
    1,240
    Any thoughts on the pros and cons of using Behavior Designer for mission scripting? I know the focus is on AI, but I've started converting one of my game's missions over, creating the actions and conditions I need as I go.

    My current method for handling mission logic is a code-only approach. I'm more of a coder and haven't typically found using visual nodes for stuff that appealing, but since most missions are basically: wait a bit, play a message, wait a bit, spawn enemies, wait for wave to be destroyed, wait a bit, dock with Ship A, wait a bit, etc, it can get a little ugly. I'm constantly waiting for the next timer to fire. It's not really that bad, but not terribly readable. It's possible that a bunch of nodes to replicate that won't really be an improvement, but at least it's a way to learn a bit about behavior trees (I'm totally green on those).

    I had thought about that approach anyway, then recently I saw this article pop up:
    http://www.gamasutra.com/blogs/SamIzzo/20160517/272814/Behaviour_trees_for_missions_and_AI.php

    One difference is that their behavior tree implementation is like a big list, which may be more appropriate for that use case.
     
  12. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    I've seen people use behavior trees for much more than AI so using it for handing missions doesn't seem like much of a stretch. Some of the unique ways that I've seen them used are for managing audio, handling gui states, and being a complete game manager. I definitely don't think using behavior trees for handing missions is as much of a stretch as being a game manager.

    Having a list view would probably be more convenient for this use case, and you would also only need the most basic features but it could be a fun experiment to try to see if it speeds up your workflow. It sounds like it worked for Defect. Towards the end they describe the problems that they had, with one of them being a lot of nodes and the other being a performance issue because the tree traverses at the root node every tick. I can't help with the node count but Behavior Designer does not traverse at the start every tick so you don't have that performance consideration (conditional aborts are used instead)
     
  13. Steve-Tack

    Steve-Tack

    Joined:
    Mar 12, 2013
    Posts:
    1,240
    It's hard to beat the expressiveness of coding, especially for missions where I'm doing something especially unique. But for many missions, the behavior tree approach might be interesting and might even encourage me to make longer and/or more complex missions. The nice thing is that I've structured it so that I can either fully code them or use a behavior tree as needed, so I don't need to fully commit to one or the other.

    I currently have a code-only FSM for my AI; I suspect that's an area where the benefits of converting to a behavior tree will be more obvious.


    Good to know!
     
  14. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    416
    Justin,

    I have a character where I switch between user control through input and Behavior AI control. I'm running into some trouble trying to stop behaviors and reseting things when I switch to user control. I thought I could use ResetValuesOnRestart. I don't know if this is a bug but more likely I just don't understand Inheritance and reflection well enough. (You mention on your website in the forums that ResetValuesOnRestart uses reflection)

    Here is my problem:
    I grab references to various components in the OnAwake method from an inherited class. My inherited class is setup exactly like your NavMeshMovement.cs class from the Movement pack except my component variables are public so I have access to them in my tasks. If ResetValuesOnRestart and RestartWhenComplete is checked , those component references are lost and I get null references. The same thing happens on your Seek example. In NavMeshMovement.cs, you grab a reference to the NavMeshAgent in OnAwake(). if you change navMeshAgent from private to public, navMeshAgent will throw null references when you use ResetValueOnRestart and RestartWhenComplete.

    Why are component references lost using ResetValueOnRestart in inherited classes if the component variables are public?

    Thanks
    Allan
     
  15. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    So how can I see the same null references that you are seeing? I just enabled Restart When Complete and Reset Values on Restart within the Seek example of the Movement Pack and it worked without throwing any errors.
     
  16. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    416
    Did you change navMeshAgent from private to public in NavMeshMovement.cs?

    You don't get the null reference until you make that reference public.

    1. Go to line 13 in NavMeshMovement.cs and change navMeshAgent to public.
    2. Open the Behavior Designer Movement scene, select the bot, select RestartWhenComplete and ResetValuesOnRestart on the Seek behavior component.
    3. Press Play and cycle to the Seek sample using the GUI.
    4. When the bot find it's target and the tree Restarts and Resets, you get a null reference.
     
    Last edited: May 20, 2016
  17. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    There we go. The reason the null reference is occuring is because when Restart When Complete is enabled the tasks don't go through the OnAwake callback again so when the navMeshAgent value is reverted it'll go back to being a null reference. Maybe the values should be saved after OnAwake is called instead of before? I'll need to think about this change some more since it could impact people who are using Restart When Complete and expect the values to be the original values. Specifically for the navMeshAgent filed you could assign it before the tree starts and that would prevent the error.
     
  18. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    416
    Justin,

    Does this only occur in an inherited class or does it apply to every task's OnAwake method? I have so far been using OnAwake for all of my component referencing because I felt it would be more performant than getting those references every time a task started...using OnStart.

    I'm also wondering if there is a way that you could add a public method call on behavior that allows you to reset values anytime during runtime instead of just on Tree Restart. So perhaps instead of changing how ResetValuesOnRestart works, instead add a method that allows you to reset values in a tree anytime. Right now in order to restart a tree from code I use
    Code (CSharp):
    1. behavior.DisableBehavior();
    2. behavior.EnableBehavior();
    would it be possible to add a behavior.ResetValues();

    Allan
     
  19. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    That is correct. Use OnAwake to cache the references.

    You were close - it's called behavior.SaveResetValues(). On first run it'll save the all of the public values, and then on subsequent runs it'll reset them.
     
  20. llJIMBOBll

    llJIMBOBll

    Joined:
    Aug 23, 2014
    Posts:
    578
    Holy Sheet, I didn't even see the Inspector inside the BD window, I almost clicked everywhere before but cudn't get it to work.
    Just had to hook up the waypoints inside the Inspector inside BD window and it works :D

    Sorry Man & Thanx again, I'll watch the videos and doc you provided and learn this :D. I've never used an node based editor before so this will good to learn.
     
    hopeful and opsive like this.
  21. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    416
    It's definitely worth the time and effort once you get the hang of it. :) The thing to keep in mind is that learning to develop using behavior trees is a little like learning a new programming language. In some ways it's even more challenging because your not just learning new syntax but you're also learning new logic structures, new ways of thinking. With that said, I have my game characters doing complex sequences of behaviors that would have been nearly impossible for me to achieve in C# because after a certain point the code just becomes a spaghetti mess of enums, switch case statement, if thens upon nested if thens. As long as you're aware of the challenge and you begin in small steps, the payoff is worth it.

    My current challenge is getting better at getting the rest of my code to interact nicely with my behavior trees but thankfully there are numerous things built into Behavior Designer that helps with that.

    Allan
     
    opsive likes this.
  22. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    416
    For my own education, can you explain to me specifically why this only occurs when the variable is public vs private? I'm assuming it has something to do with when the variable is public, it's exposed, and you handle public variables differently?

    It's funny but I knew the variables were losing their references due to OnAwake not being called again and my solution to that was to reestablish those references using the OnReset() method. It seemed perfectly logical that OnReset() would be designed to reestablish those lost references due to using ResetValuesOnRestart. When OnReset accomplished nothing (because it's an editor feature only), that started my quest to figure out hat the heck was going on with these lost references. :)
     
  23. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    That's correct. When ResetValuesOnComplete is enabled it'll only save off and restore the public fields. Private fields are not touched so that's why you don't get a null reference when navMeshAgent is private. I'm still going back and forth on when the public values should be saved (before or after OnAwake) and right now I'm leaning towards changing it so it is after OnAwake. My original thinking was that all of the public variables would be assigned before the tree starts so that's why it should be saved off before OnAwake.
    OnReset is an editor only function that has existed since Behavior Designer 1.0. ResetValuesOnComplete was introduced in 1.5.x so I didn't want to rename an original function. OnReset gets called when you click the gear icon within the task inspector:

    reset.png

    In theory you shouldn't need to do anything differently when ResetValuesOnComplete is enabled.
     
  24. Craftomega

    Craftomega

    Joined:
    Sep 3, 2013
    Posts:
    2
    I am looking at several options for AI for the projects I am working on and Behavior Designer has come up as an ideal solution many times. Does Behavior Designer support Curves? For something like a Utility AI?I looked through your documentation but could only find "Is Parameter Controlled By Curve" But nothing on setting variables within a curve.
     
  25. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Yes, tasks do support curves. There are no built in tasks which mimic utility AI functions though so you'd have to create those.
     
  26. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Hi. I have been using BT for my game Subterrain, and it has been really good so far. But I am porting the game to Xbox one and I am wondering if BT would work under heavy AOT platform. (so no JIT issue).
     
  27. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    I can give some insight into this before Justin gives an official response. I develop on the Wii U, which is also AOT. Initially there was a serialization problem and I had to specify JSON serialization. After that, everything seemed to work fine. I have to say though that I have not yet used it extensively, but I did create a small, fully working behavior tree for an enemy and it ran on the Wii U.
     
  28. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    for serializtion part.. when will that be matter? to save BT to disk? I am not doing anything like that but all the BT is just sitting on the prefab.. is there option I need to turn on? (even if I use if just like that?)
     
  29. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    It's important just for having the BT data itself. Without it, the BT won't run properly. To turn it on you just have to select it by clicking the Preferences button in the top right corner of the BT editor and select it. But I actually think JSON is the default now so you probably don't have to do anything.
     
  30. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Thanks for the help @magique!

    @magique is correct - Behavior Designer does support AOT platforms. We had a problem on the WiiU with binary serialization but there have been a few changes since then so it's worth giving another try. In any case JSON serialization definitely works and can be changed within the Behavior Designer preferences.
     
  31. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    It's good to know ! thanks!
     
  32. RemDust

    RemDust

    Joined:
    Aug 28, 2015
    Posts:
    432
    Newbie question here but just wanted to check this :
    Is this possible to use Behavior Designer with our own custom behaviors and just take advantage if its "workflow" and logic features ?

    As I'm working on 2D games, most of the implemented tasks won't be really useful but I was working on a "behavior manager" and B.D. seems to be really great for that !
     
  33. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    Justin may want to elaborate on this, but I know you can easily create your own behavior tasks and use them in Behavior Designer. Here is a video on writing your own tasks.

    http://www.opsive.com/assets/BehaviorDesigner/videos.php?id=3
     
    opsive likes this.
  34. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Yes, you can definitely use Behavior Desiner with a 2D game. The base behavior tree doesn't care if the game is 2D or 3D. In addition to what @magique mentioned, there are a lot of built in 2D tasks as well covering the Unity API. The Movement Pack without any integrations requires 3D due to Unity's NavMesh not supporting 2D. The PolyNav integration allows for 2D movement though. Unity is working on a 2D NavMesh implementation so as soon as that is implemented I'll make sure the Movement Pack supports it.
     
  35. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    BT has been really good.. and I am using it on Subterrain, top down 2D game. the most challenge that I have with it is to reduce GC, but with many different nodes and with movement pack using physics to detect stuff, it is a bit of issue, but I am modifying them to reduce the GC as much as possible.. (since these things run per frame..)
     
  36. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Unity 5.3 introduced non-allocating physics functions which the Can See/Hear tasks would benefit from. Thanks for the reminder - I'll make sure this is included in the next update.
     
    hopeful likes this.
  37. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Oh really??? wow.. where did you see that news? was it on the release note? I want to check it out too! I will probably have to do this myself, because I have already modified the movement pack Can see/hear etc..
     
  38. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Take a look at the Physics API page - you'll find that the majority of the raycast functions have a NonAlloc version now:

    http://docs.unity3d.com/ScriptReference/Physics.html
     
  39. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Ok, I may not understand it fully yet, but if allocation is happening because of Raycasthit[] or such, then , what is difference between providing own buffer to fillin? Because the "provided" buffer would also eventually be allocated? (since it doesn't know how many it will hit etc..) At glance, it just looks like getting the result from function return call or referenced buffer.. I maybe wrong (probably wrong) but if GC is happening inside actuall call to the physics engine, why did Unity made the function call looking different.. ? :D
     
  40. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    The difference is when that buffer is allocated. With previous functions the buffer is allocated with each function call. With the NonAlloc version it is allocated once at the start and then your done. You will need to know the absolute maximum number of objects ahead of time though
     
  41. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    i see! so like allocate 100 and then send that as ref.. but how do you know how many... oh wait.. i see.. that is what gets returned.. excellent.. got it.. makes sense now!
     
    opsive likes this.
  42. coder_for_life22

    coder_for_life22

    Joined:
    Dec 25, 2013
    Posts:
    46
    Hello,

    This question may have already been answer but, how does wander work? I have a game that has lots of walls. Does the wander allow walls to be taken into account? Or how does this work?

    One I know the answer to this ill be purchasing this awesome plug-in. Just what I needed!
     
  43. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Sounds great - wander works by randomly selecting a position and then using the underlying pathfinding implementation to move towards it. If the random position is on the opposite side of the wall it'll pathfind around it. If you want to keep the agent within a specific area you could mark the outside area as not traversable..
     
  44. coder_for_life22

    coder_for_life22

    Joined:
    Dec 25, 2013
    Posts:
    46

    Awesome! So there is an option to make the agent move within a specific area?
     
  45. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Not within the actual task, but you could mark the area as not traversable by the pathfinding implementation that you are using. Alternatively you could place an invisible static object in the opening to prevent there being a valid path to the opposite side of the wall.
     
  46. coder_for_life22

    coder_for_life22

    Joined:
    Dec 25, 2013
    Posts:
    46


    So does the Behavior Design include pathfinding? Or there is there an extension for that?
     
  47. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    The base Behavior Designer asset is a dedicated behavior tree implementation so it does not include any pathfinding. There are a few tasks which allow you to change the NavMeshAgent properties but the real power comes with the Movement Pack. The Movement Pack uses Unity's NavMesh by default but is also integrated with A* Pathfinding Project, Apex Path, and PolyNav.
     
  48. coder_for_life22

    coder_for_life22

    Joined:
    Dec 25, 2013
    Posts:
    46
    I see! So the behavior movement pack does not require the purchase of a* pathfinding or any of the others but comes integrated? If I understand correctly? And this would allow me to use the nontraversable areas features like we discussed above?
     
  49. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Yes, with Unity's navmesh you can block the exit with a NavMeshObstacle:

    http://docs.unity3d.com/ScriptReference/NavMeshObstacle.html
     
  50. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    Justin may have misread this. Per his response, yes, you can use NavMesh pathfinding with the Movement pack so no other purchase is necessary to achieve pathfinding, but A* and other pathfinding packages are not included free of charge. You get integrations to those packages, but you need to own those packages.
     
    opsive likes this.