Search Unity

Behavior Designer - Behavior Trees for Everyone

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

  1. dl290485

    dl290485

    Joined:
    Feb 4, 2018
    Posts:
    160
    Ok, so now I know more about the aborts.

    However, how can this be used (or another action) so that ending an action can pass through a temporary transitional action? What I mean is, I want the AI to go back to searching (not knowing automatically where the target is) if the target goes out of sight, but how can I maybe delay this with a timer or maybe insert another action in between? (like maybe a very short range wander or 360 spin).

    The reason why I need this is because the AI is very easy to beat by simply running past or circling around it quickly. I want it to lose sight of the target, but it should have the sense (or at least simulated sense) to turn around if a target just passed by. This can be recreated by letting it still know where the target is for an extra second or something. This can be like guessing where they went.

    How may I achieve this?

    Thanks for anyone help and apologies for these really basic noob questions.
     
  2. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Take a look at this page - http://opsive.com/assets/DeathmatchAIKit/documentation.php?id=3. This goes through a pretty complex tree and one of the things that it does is search for the target if it goes out of sight. It also uses a timer for deciding how long to search for. Here is another smaller tree that has similar functionality with searching for an object:

    http://opsive.com/assets/BehaviorDesigner/documentation.php?id=119
     
  3. thedrhax14

    thedrhax14

    Joined:
    Aug 7, 2014
    Posts:
    38
    Hi @opsive, could you please check thread I made about SendEvent? I have a problem with usage of SendEvent method.
     
  4. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
  5. thedrhax14

    thedrhax14

    Joined:
    Aug 7, 2014
    Posts:
    38
    Thank you very much. Here is what I was looking for:
     
    opsive likes this.
  6. Snouto

    Snouto

    Joined:
    May 27, 2013
    Posts:
    9
    Hi Opsive

    I'm experimenting with BD for a game idea I have. I'm only a few days in to it and there's still a lot I don't fully understand, but with that said I feel like I'm doing something wrong or missing something fundamental that is blocking me from moving forward.

    Attached below is a screen grab of my tree. I'm using the movement pack for A* with this.



    In pseudo speak what I want to do is:

    1) wander about the scene navmesh, until a "food" item is visible. Break from this section once food found
    2) Move to the found food item. There may be more than one character in the scene also moving towards the food item so I need to make sure, once I get to the food position, that it is still available (I do a simple tag check to see if it has been changed in the meantime). If the food is still available, parent it to the character so it has been collected. If the food item is no longer there, go back to step 1.
    3) With the collected food item, move to the base object in the scene. Upon arrival, destroy the food item, reset some flags, then go back to step 1.

    Conceptually this should be really easy but I'm having a difficult time getting it to work. The tree above is several iterations of changes I've made in an attempt to get the thing to work but, as indicated in the image, when it comes to the point of returning to the base object the tree immediately succeeds that task and continues. This basically means that as soon as I've parented the food object to the character it's immediately destroyed without any navigation back to base.

    [EDIT] Having put a breakpoint on the Seek task, it appears it will actually work if I click the step button a few times. After a few Step clicks the character starts to move towards the base and if I let it play from there it works as I would expect. Without the breakpoint it fails as described above - is this some kind of timing issue?
    [Edit 2] I should also perhaps mention that I'm using the recently updated AIPathAlignedToSurface agent script for moving the character around, along with a Recast Graph for the pathfinding.

    I can't quite understand what is happening here and I've tried several different interrupt states in the first section in case that was immediately interrupting the base seek phase, but nothing makes a difference.

    Could you hit me with some knowledge? I'm sure this is not the best way to do what I need to do but right now I'd be happy just understanding why the current approach is failing.

    Cheers :)
     
    Last edited: Jul 25, 2018
  7. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    It looks like you have a conditional abort setup for the first branch of wondering for food - this is likely why the seek task is being aborted. Right now you just want to get things done linearly so try removing the conditional aborts and see if the basic flow will work. You can then build upon that and decide when certain branches should be aborted.
     
  8. _watcher_

    _watcher_

    Joined:
    Nov 7, 2014
    Posts:
    261
    Hi,

    Say there is a tree with 2 branches, first branch Sequence with lower priority abort and some leaf conditional/action stuff. Second branch is Sequence with its own conditional/action stuff. This tree executes correctly, in that when the right branch is active, and the left branch conditional evaluates from Failure to success, it aborts the right branch and starts executing the left branch.

    Now, lets replace the lower prio abort Sequence task with lower prio abort Parallel task.

    The new tree does not abort anymore. Why does Parallel task not get re-evaluated each frame, and why does it thus not abort anymore, where Sequence task does? Is there some other functionality the Parallel task has besides just executing its children "at once" in comparison to Sequence task, that executes them sequentially? I'm also curious what "at once" means. Does it mean, it still executes from left to right, but in 1 frame, and does it mean Sequence executes its children from left to right, but over N frames (where N = number of children)? (what does "parallel" mean in single threaded Unity? Sometimes I find the descriptions extremely vague, with further need of self-testing the functionality).
     
    Last edited: Jul 25, 2018
  9. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Parallel tasks reevaluate each child (from left to right) every frame (within the main Unity thread) so there's no need to use conditional aborts with parallel tasks - the task is already being reevaluated. You can use the different parallel tasks (Parallel, Parallel Complete, Parallel Selector) to change how the parent task responds to a child task completing.
     
    _watcher_ likes this.
  10. Snouto

    Snouto

    Joined:
    May 27, 2013
    Posts:
    9
    Thanks for the reply I tried your suggestion but I had to have at least one abort to ensure the wander could be interrupted, and the result was the same anyway. That Seek action just does not want to run.

    Anyway I tried reworking the tree to be a little better (maybe) and this is how it looks now:


    Yet, despite this reworking (along the lines of some examples I've seen from you such as character controller and solo), and despite it working as expected for the most part, that Seek action in the first branch still does not work.
    I'm thinking either I'm doing something spectacularly wrong or there's an issue somewhere else either with BD or A* or a combination of the two. My BD tree asset for the above is here if it helps at all.

    Would appreciate any insight as this is really starting to irk me!
     
  11. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Can you record a video of the tree when it fails when you thought it should succeed?
     
  12. Snouto

    Snouto

    Joined:
    May 27, 2013
    Posts:
    9
    No problem, I've sent a link to the video I've just created to your inbox. Thanks for the help!
     
  13. thehen2

    thehen2

    Joined:
    Apr 1, 2014
    Posts:
    54
    I have an event system in my game, and I need my tasks to subscribe/unsubscribe from these events.

    Using OnAwake I can subscribe to Unity Events, but there is no OnDestroy method to override, so I can't unsubscribe from those events.

    Any help would be great.
     
  14. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    You can use OnBehaviorComplete which gets called when the behavior tree ends.
     
  15. WinterboltGames

    WinterboltGames

    Joined:
    Jul 27, 2016
    Posts:
    259
    @opsive

    After I have bought the asset and watched some tutorials I'm amazed but I'm kind of stupid since I have a behavior tree with the following structure...

    Entry => Repeater (Forever) => Sequence => Find With Tag & Selector With => Wander & Sequence With => Within Distance & Seek

    What am I trying to do is have the AI follow the player if he is nearby and wander around if he isn't
     
    Last edited: Aug 4, 2018
  16. dienat

    dienat

    Joined:
    May 27, 2016
    Posts:
    417
    I saw the surround movement in the movement pack but i wonder if there are obstacles in middle of that circle, what the enemies would do? try to reach that goal that they cannot reach cause there is an obstacle that cannot be avoided all the time ignoring to attack player? for instance lets say the player opens a door, and one monster gets to go through it and player stays in the door and he has enemies in the back and the front but enemies try to place in a certain position in the circle all the time or just position in the nearest place to his position in the circle they can reach and attack the player?
     
  17. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    You'll want to structure your tree similar to the tree at this time within the overview video:



    Instead of Can See Object you'd have Within Distance, and instead of Idle you'd have Wander. You can still have Find With Tag at the start so the Within Distance/Seek task will know what to look for. Wander never ends so you do not need the repeater.
     
    WinterboltGames likes this.
  18. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    You're talking about Surround from the Tactical Pack, correct? If there is an obstacle in the way the agent will not fire, but it also will not try to move into position. If an obstacle is in the way it would be a pretty small change to have the character start to seek towards the target instead of staying in the same position.
     
  19. WinterboltGames

    WinterboltGames

    Joined:
    Jul 27, 2016
    Posts:
    259
    Now, this is really annoying...

    Here's my tree what's wrong with it? within distance returns true even if the target gameObject is 99999999 km away!

    and the agent keeps seeking the player which is not the desired behavior!

    BehaviorScreenshot.png
     
  20. dienat

    dienat

    Joined:
    May 27, 2016
    Posts:
    417
    Yes, the surround from tacticak pack. And you can set up how near the enemy can reach the player, cause its not the same a dragon than a skeleton, the dragon will need to be very far from the player to start attacking
     
  21. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Your tree setup looks good so it's probably a setting within Within Distance. There is a lot that can go wrong with this so I've found the best way to debug it is to set a breakpoint within WithinDistance.OnUpdate and see where it returns true. Based on your explanation it sounds like the magnitude is incorrect. One of the first things that WithinDistance does is a overlap sphere cast to determine which objects are nearby. My guess is that this cast is including your target when it shouldn't be.
     
  22. WinterboltGames

    WinterboltGames

    Joined:
    Jul 27, 2016
    Posts:
    259
    My god, I'm so stupid...

    I watched that video where you explain abort types and founds that using both abort type does the job for me!
     
  23. WinterboltGames

    WinterboltGames

    Joined:
    Jul 27, 2016
    Posts:
    259
    One more question, How can I reference child animators when I have a SetBool node?
     
  24. Snouto

    Snouto

    Joined:
    May 27, 2013
    Posts:
    9
    Hi @opsive me again, I just updated to Unity 2018.2.2f1 Personal and noticed some of the Seek tasks (yeah, them again) are failing to end, resulting in my character stopping movement (probably because they have actually arrived at the end of the current A* path). It may be completely unrelated to the latest Unity build but just wondering if you've observed anything like this with the latest Unity build?
     
  25. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    The SetBool task is for setting the bool of a shared variable. The SetBoolParameter will set the animator parameter and that takes a target GameObject which you can specify the GameObject that the animator belongs to.
     
    WinterboltGames likes this.
  26. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Can you tell me how to reproduce it from the Movement Pack scene? I made a similar test case to your last example where the A* agent seeked to multiple targets and it correctly traversed both paths.
     
  27. xqin

    xqin

    Joined:
    Nov 15, 2016
    Posts:
    2
    Hi, Excuse me , I have a question。Is there any way to preload the Bt tree , our tree is complex, and When choose start on enable, the game become lag。Can we use the Function Init in BehaviorSource?
     
    Last edited: Aug 13, 2018
  28. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
  29. xqin

    xqin

    Joined:
    Nov 15, 2016
    Posts:
    2
  30. lo-94

    lo-94

    Joined:
    Nov 1, 2013
    Posts:
    282
    Hey there, new to the asset and I have a few quick questions

    Firstly the "Can See Object" check, I noticed that even if I set the target tag to something like "Food", it often still returns a gameobject without that tag. Is there a reason for this or is it a known issue? It is returning objects that have Unassigned tag. I also have one check that looks in the Consumables layer for an object with tag 'Water', but the node is returning success when finding the food object (which is tagged 'Food' within the consumables layer). I attached screenshots to show the issue. As you can see the conditional for food fails, the can see food does not even run, and can see water is the only node executing. Yet it is returning success on the food object even though the tag set is 'Food' on the object and 'Water' on the node itself. Am I doing something wrong or is the tag functionality currently broken? This only happens on the can see object node, when it goes to check the tag later (for a conditional to determine the type of resource consumed) it determines that the tag equals food, and sets isHungry to false.

    Second question, when I create an external behavior tree, say I modify one of the scripts (I modified the wander script from the movement pack) and I want to be able to set the animator of the object using the wander object. When I drag the animator to the variable slot within the scene for my AI, it modifies the external behavior tree and throws an error. What's best practice to avoid this? I tend to avoid doing that within Start or Awake for performance reasons

    CanSeeBug.PNG CanSeeWaterSetTargetObject.PNG CanSeeWaterSetTargetObjectDetails.PNG CanSeeWaterSuccess.PNG
     
    Last edited: Aug 14, 2018
  31. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    The Can See Object task will check for objects in the following order:

    Target Objects List
    Target Object
    Target Tag
    Object Layer Mask

    Within CanSeeObject.OnUpdate which condition gets executed? Is it:

    Code (csharp):
    1.  
    2. returnedObject.Value = MovementUtility.WithinSight(transform, offset.Value, fieldOfViewAngle.Value, viewDistance.Value, GameObject.FindGameObjectWithTag(targetTag.Value), targetOffset.Value, ignoreLayerMask, useTargetBone.Value, targetBone);
    3.  
    What is the error that you are getting? It sounds like it could be related to:

    https://legacy.opsive.com/assets/BehaviorDesigner/documentation.php?id=137
     
  32. lo-94

    lo-94

    Joined:
    Nov 1, 2013
    Posts:
    282
    I see the issue
    It's on line 83 of CanSeeObject.cs
    There's a conditional else if that checks if the targetObject.Value is null. If it is, it executes that. The else if after it checks if it has a targetTag and executes if it does, but if you don't set the object then it will ALWAYS search by layer and never by tag

    I'm going to try and tweak the WithinSight method in MovementUtility.cs so that it performs the OverLapSphere and then grabs the closest one with the desired tag and returns that instead of it just being based on the layer
     
    Last edited: Aug 14, 2018
    opsive likes this.
  33. joaobsneto

    joaobsneto

    Joined:
    Dec 10, 2009
    Posts:
    152
    Am I the only one having serialization problem with Unity 2018.1 and 2018.2? Problems I had:
    1) I make a copy of a external tree. I edit the copy and the source is also edited.
    2) I have a prefab that references a external tree, the BehaviorTree component in the the prefab does not update the variables fields. And if you change a variable in the external tree I have to remove the BehaviorTree component and add it again to make it work properly.
    3) Sometimes the variables are not store in the external tree. I add a variable, make its references, close Unity and open again the variable is missing, but if I add a variable with the same name, the links are made automatically.
     
  34. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    I haven't seen any recent reports of serialization issues but I have a few questions:

    - Are you able to reproduce it within a fresh project?
    - Did you upgrade your tree from a version prior to 1.5.8?
    - What error are you getting?
     
  35. djgriff

    djgriff

    Joined:
    May 29, 2014
    Posts:
    279
    Hello,

    I would like to know how to get a gameobject from behavior designer via code?

    So i am making a multiplayer simple game but i want to get the Target gameObject from the Enemy a player then deal damage.

    I have created a custom task but can't get the target assigned to the Task.

    If i create a public gameobject _target. I can see the gamobject field in the task in the tree to deal the damage to the platyer but i cant assign the Global Target gamobject variable to the gamobject slot. I dont get the little square symbol to choose any variable.

    Not sure if i am going about it in the right way.

    What i am trying to acheive is deal damage to the multiplayer player from that monster/enemy.

    I have all the addon packs but not sure how to use the Attack node/task.

    Many thanks


    Daniel
     
  36. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    The little square symbol will appear if you have used a SharedVariable for the field:

    https://legacy.opsive.com/assets/BehaviorDesigner/documentation.php?id=50
    https://legacy.opsive.com/assets/BehaviorDesigner/videos.php?id=3

    You can specifically set the variable through code using the Value property:

    https://legacy.opsive.com/assets/BehaviorDesigner/documentation.php?id=54
     
  37. djgriff

    djgriff

    Joined:
    May 29, 2014
    Posts:
    279
    Cool thanks
     
  38. IsntCo

    IsntCo

    Joined:
    Apr 12, 2014
    Posts:
    146
    How do you stop an A* star agent with Behavior Designer/Movement Pack? Tried doing my own action for using "isStopped" but it seems like Behavior Designer takes control immediately.
     
  39. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Is the tree still active? And stop the agent within the tree? If so probably the easiest way would be to use the seek task to set the destination to the agent's current position.
     
  40. whudu

    whudu

    Joined:
    Nov 25, 2016
    Posts:
    2
    Hello @opsive ; It seems "Seek" task is going till it catch the object. I couldnt organize something like that. I want boss seek player but if player moves to out of range it stops seeking and continue patrolling. How can i handle it?
     
  41. LinZhiChao

    LinZhiChao

    Joined:
    Sep 5, 2018
    Posts:
    2
    HI,how to save BehaviorTree as XML File Type
     
  42. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    You could combine the seek task with the Within Distance task to stop seeking. I do this with the Third Person Controller tree and it is explained in the Can See branch (just over half way down the page):

    https://legacy.opsive.com/assets/BehaviorDesigner/documentation.php?id=119
     
  43. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Behavior Designer doesn't support XML but you can export as JSON. This can be changed in the Behavior Designer preferences on the top right of the editor.
     
  44. whudu

    whudu

    Joined:
    Nov 25, 2016
    Posts:
    2
  45. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
  46. LinZhiChao

    LinZhiChao

    Joined:
    Sep 5, 2018
    Posts:
    2
    The JSONSerialization content is stored within one line. Our designer prefer structural XML type.
    Anyway can we purchase BehaviorDesigner Editor source code? (not runtime code)
     
  47. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    We currently do not have a license for the editor. Newlines are inserted though so you should be able to have the JSON output to multiple lines. Make sure you are using text serialization in Unity. If that doesn't work feel free to send me your tree to support@opsive.com.
     
  48. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    Behavior Designer 1.5.13 has been released on the Asset Store. This update is mostly a compatibility update for the new opsive.com server.
     
  49. madmaxim

    madmaxim

    Joined:
    Feb 11, 2013
    Posts:
    6
    Hi,

    Was trying to figure out a way to add tasks to a behavior tree dynamically at runtime via code, eg I have a sequence and would like to add tasks to that sequence. I see the write-ups on External Behavior and Ref Tasks, but that still looks like you need to place it into the tree beforehand and doesn't have the flexibility (I think) I need. I saw the ParentTask AddChild method but having trouble figuring out how to get that work. So far it just causes havoc in the BD editor window :( Any help appreciated!
     
  50. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,127
    The external tree method and overriding GetExternalBehaviors is correct - you will need an external tree ahead of time though. Since Behavior Designer uses a data-oriented design the structure has to be in place beforehand. You could also create the entire tree at runtime by following this: http://legacy.opsive.com/forum/index.php/topic,4118.msg21580.html#msg21580
     
    madmaxim likes this.