Search Unity

AI: Behaviour trees in Unity: Behave 1.1 released

Discussion in 'Assets and Asset Store' started by AngryAnt, Sep 29, 2010.

  1. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    Having good success with Behave - fantastic framework, Emil! Wonderful. Works great with Unity javascript as well.

    I have a question about Decorators, not as much as how they are implemented in Behave, but Decorators in general with regards to Behavior Trees:

    Given that I am new to Behavior Trees and AI (as well as OOP), why and when do you use a Decorator as opposed to just coding all the behavior as part of the Action method. I am finding I can do it either way, seems easier right now with simple BT's to put all the decision code in the Action node. Are Decorators used for flexibility in a more complex BT? For instance, let's say you have an action to choose a target - and that action is used say, 12 different places in the tree. But the criteria for choosing a target change depending on what's going on in the game. So would you use decorations to implement the decision code for the ChooseTarget action based on some criteria of the game environment?

    I've been reading up on BT's and 'm not sure if Im understanding Decorators correctly. Thanks for any help explaining this.

    Again, Behave - fantastic Unity plug in!

    Mitch
     
    Last edited: Feb 27, 2012
  2. SilentWarrior

    SilentWarrior

    Joined:
    Aug 3, 2010
    Posts:
    107
    I am having the same troubles. From what I understand Decorators are use to "decorate" (provide extra information, initialize/update variables and provide extra meaning) the nodes below. However I fail to see the usefulness behind them when you can do it easier in the code of the action. I actually want to learn this because there must be a better reason why decorators were "invented".

    Also, why isnt there a node that simulates an "if" condition? Is it because of lack of time? Or is it by design? There must be a reason why more complex node types are implemented and something simple as a branching IF is not. Maybe I am not using my behavior trees correctly, but I keep getting mixed up in emulating IF conditions using selectors and having wierd problems and WAY too many nodes just because of that.

    How I suggest the "IF" node would be, 1 input, 2 output, if condition = Sucess go on into output 1, if not go on into output 2, what ever the child returns so does the if node (sucess, fail, running). It would be just a branching control, like those rail switches in the railroad systems, if lever is in position1, train goes left, else, train goes right. Having it work as a short-circuit like a Decorator would be awsome too but with a little tickbox, something like, if "hasTarget" proceed and do this branch, if for watever reason "hasTarget" is no longer true, switch branch.

    This would make the whole tree above it much simpler too, because, if the first branch fails, I know that it has already tried both branches and failed. The tick box would allow for : switch condition return fail.
     
  3. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    Maybe someone with more experience can weigh in, but I think Selectors provide an IF type behavior. Say you have two action nodes as children of a Selector. If the condition in Action A fails and returns a Failure then the Selector goes to the next Action node -- Action B. So that is very much like a IF THEN ELSE.
     
  4. SilentWarrior

    SilentWarrior

    Joined:
    Aug 3, 2010
    Posts:
    107
    Except it will return up the tree instead of selecting a branch. What if I have a ton of other nodes under it? Because... well its a IF.

    IF playerHasLineOfSight -> continue into managing turret rotation, aim, shoot etc. Else ... etc

    The selector will say : if playerNotHasLineOfSight, continue into next nodes, but doesnt let me the option of TRUE. If I want both true and false, then I will have to make my tree check the same condition 2 times, each time.
     
  5. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    154
    Hello,

    I'm stumped as to what could be wrong with my tree. I am attempting to use a "filter" style of decorator to only fire its children every so many seconds. It is my intention for the children to return BehaveResult.Running. It is my understanding that if a child of a Decorator returns BehaveResult.Running, that the Decorator is supposed to allow its children to run regardless of if the Decorator is currently true or false.

    I believe my error is in how I am implementing the Decorator code to allow this to happen. What is happening is that the Decorator allows its children to run exactly once, even though TickMoveAction returns BehaveResult.Running

    Here is a screenshot of my tree and my implementation. Do I need a combination of Init, Tick, and Reset methods for my Decoration to pull off "filter" functionality?

    Thank you in advance. I'd really like to get a handle on Behavior Trees.

    Code (csharp):
    1.  
    2. public BehaveResult TicktimePassedDecorator(Tree sender, string stringParameter, float floatParameter, IAgent agent, object data)
    3.     {
    4.         Debug.Log(Time.time + " > " + time + floatParameter + "?");
    5.        
    6.         if (Time.time > time + floatParameter)
    7.         {
    8.             Debug.Log("timePassed success");
    9.             time = Time.time + floatParameter;
    10.             return BehaveResult.Success;
    11.            
    12.         }
    13.        
    14.         Debug.Log("Failure");
    15.         return BehaveResult.Failure;
    16.     }
    17.  
    18. public BehaveResult TickMoveAction(Tree sender, string stringParameter, float floatParameter, IAgent agent, object data)
    19.     {
    20.         if (Time.time > moveTime + floatParameter) //If 5 seconds of movement have passed, return success.
    21.         {
    22.             Debug.Log("Move Action Sucesss");
    23.             return BehaveResult.Success;
    24.         }
    25.  
    26.         Debug.Log("Move Action Running");
    27.         transform.Translate(heading * Time.deltaTime);
    28.  
    29.         return BehaveResult.Running;
    30.     }
    31.  
     

    Attached Files:

  6. Srch

    Srch

    Joined:
    May 28, 2010
    Posts:
    8
    Hi Tylo,

    I think you need to have your decorator return running to keep executing the child node, also on page 7 of this thread there is an example of a decorator used to only fire at a set frequency, hope this helps.
     
  7. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,657
    Feature request:

    Make it possible for editor code to set which tree the debug window is inspecting.

    When I've got 20+ instances of the same tree in my scene, and I'm trying to diagnose the strange behaviour of one particular agent, it's annoying to track down which tree is his - I have to rename him to something unique, and then click through each tree in turn checking to see which one lists him.

    If I could set the currently debugged tree in editor code, I could write a quick custom inspector for my agent component with a 'debug tree' button that opens up the debugger with his tree selected.

    [edit: ah I guess I'll go post this on github]
    [edit2: no wait nevermind, that seems to be for bugs, not feature requests]
     
  8. Metron

    Metron

    Joined:
    Aug 24, 2009
    Posts:
    1,137
    Ignore this message... you have never, ever read it...
     
    Last edited: Mar 7, 2012
  9. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    Still learning the ways and means of behavior trees. All going well with Behave. My question:

    Is it advisable to dynamically change the frequency of the tree's tick loop under certain game conditions? I'm just playing around at this time and for evaluation purposes my tree ticks at 1 tick per second. But then when my NPC needs to chase down a fast moving target I shift the tick frequency to Time.deltaTime. Then after the player intercepts the target, his tree goes back to tick at once per second.

    Is this a proper way to handle a situation like this? Or is there a another way to do this?

    Thanks for any help.

    Mitch
     
  10. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    I have 2 questions which I can't seem to find answers to in the docs:

    1] What does the 'instant" tic box do for actions and decorators? What is their purpose?

    2] Can the invert parameter be changed dynamically? Or is it just set when the Behave Library is compiled and can not be changed?

    Thanks for any help.

    Mitch
     
  11. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    I'd like to understand how to pass parameters to Actions using Decorators. I see Behave Decorators have float and string as parameters. How does one implement that in code and more to the point, is it possible to pass a GameObject or a Vector3?

    I really hope someone could take a minute to provide some help. My last few questions from weeks ago have gone unanswered.

    Nevertheless I am making fabulous progress with Behave and I have a very nice simulation running of Bots working together intelligently together picking up boxes in a warehouse and putting them in various locations based on game states.

    Fantastic stuff, but if I could just get a few questions answered I'd be in much better shape.

    Thanks for taking the time to read this.

    Mitch
     
  12. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    767
    Hi AngryAnt,

    First off, greetings, thank you for such great tool. It really helps to clean AI and make it easier to mantain. We will be honored to put your logo inside our splash screen for our game as you require in the license.

    Now that I am experimenting with Behave, I have a couple feature requests, that hopefully you agree would make behave better.

    Built in actions and decorators. Some actions and decorators are general purpose, and every developer end up reinventing the wheel. It would be great if Behave came already with some pre built decorators like
    • Wait. To wait for a specified amount of time
    • Repeat. To repeat subtree a supplied amount of time
    • Animate. To start an animation

    None of them are hard to write ourselves, but if they came built in, it would be much easier to get started.

    Expression parameters. Instead of just passing a string or float, allow the developer to put an arbitrary expression. This would allow for more reusable componets, for example I could do this:

    Code (csharp):
    1. action: wait
    2. parameter: Random.value * 5 + 5     // sleep between 5 and 10 seconds
    or this:

    Code (csharp):
    1. decorator: if
    2. parameter: Random.value < 0.30    // execute the subtree only 30% of the time
    Since you compile down to a .net assembly, you could include the expression as part of the code, no need to build an interpreter or fancy compiler.
     
  13. Leiter Jakab

    Leiter Jakab

    Joined:
    Sep 25, 2010
    Posts:
    53
    First of all I'd like to join all the others and say thanks for this awesome tool. I'm new to behaviour trees in practice although I have been following Alex's articles and videos on the theory.

    My question is about condition checks. I see a lot of people want to do them with decorators. As far as I understand you can achieve the exact same thing in two ways:



    These two setups do the same thing. They check a boolean (bMyCondition) and execute the tickmethod of ActionA if it is true and ActionB if it is false.
    (In the Decorator setup the Failure and Success comments refer to the enums returned by the tickmethod, not the one retuned to the sequence by the decorator, which is Success in both cases.)

    So is there a reason to chose decorators for this task? Is it a question of readability or performance?

    Although in the first example you could use an inverted ConditionA insted of ConditionB and call it CheckMyCondition to improve readability, right?
     
  14. Crea

    Crea

    Joined:
    Apr 7, 2012
    Posts:
    1
    I'm getting occasional, and repeated failures to compile my behave library, for non-obvious reasons. I'm sure it's not random, but it feels like it - one instance seemed to be related to MonoDevelop having some kind of lock on the assembly, closing it down allowed me to recompile the Behave library.

    But I've had it occur without MonoDevelop open, and it seems utterly unrelated to whatever Behave assets I have, i.e. it will occur on empty trees etc.

    Any ideas? Simply get an error box saying "Compiled library failed to build. Please send in the problematic behave asset to assist bugfixing".
     
  15. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    I see from Angry Ant's Behave repository on GITHUB, that there is a bug in 1.4 when calling tree.Reset(). It does not reset the Initialization of a Decorator. It Ticks the Decorator but skips the Init. He says he has it fixed for Behave 1.5, but does anyone have a working solution for 1.4?

    Mitch
     
  16. Panajev

    Panajev

    Joined:
    Mar 26, 2012
    Posts:
    42
    Hello Mitch,

    Thanks for the JavaScript code. I am trying to maintain the current codebase JavaScript only as much as possible, so I welcome this Agent class in JavaScript :). Can you tell us more about your experience in using Behave with JavaScript?
     
    Last edited: Apr 21, 2012
  17. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    DOH! I can't believe this is Free.

    I really could have used this in this weekends Ludum Dare, I was trying to add critters to a planetoid with basic behaviours, ended up just using switch case statements.

    How easy is it to use/learn?
     
  18. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    767
    From our experience:
    Documentation is not that great
    I am not going to lie, there is a bit of a learning curve.

    That said, once you get the hang of it, the framework is absolutely fantastic. Well worth the effort you invest in learning it. For us it went something like this:

    First MOB, it took 2 or 3 days to build. You start building actions and decorators for your games. Try to make them as generic and reusable as possible. An example for an action: StartAnimation(x) so you have an action that receives the name of the animation to play. You will start building a library of actions/decorators.

    Second MOB, it took 6 hours to build. Most of the time you spend modifying the actions and decorators from the first mob to make them more rehusable. And probably adding a few more specific to your mob.

    Third MOB, 1 hour. Recycle all actions and decorators from first 2 mobs, and just some additional tweaking.

    Forth MOB, 5 - 10 minutes. You already have all actions and decorators, so just create a tree with them, it is just drag drop and can be built very quickly.

    All other MOBS 5-10 minutes.


    Not only you get to create AI very quickly after the first few mobs, but it becomes very readable. You can show it to another developer, explain a little bit how behavior trees work, and have them understand it in a few minutes. You can even offload the work of creating new trees to non developers.

    It helps a lot to watch the video from AIGameDev, and to read the first few pages of this thread talking about decorators.
     
  19. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Cool what about combining this with a Steering and Navigation framework?
     
  20. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    You are quite welcome, Panajev.

    My experience with Behave is minimal. I've been at it only 3 months or so. There is not much documentation out there on Behave or Behavior Trees and I find that whatever is available is tailored for folks who are very experienced in programming. I am not a very experienced programmer so I really have to spend a lot of time struggling with trial and error to make something work.

    With that said, I am having success with Behave. I'm putting together an automated warehouse where Bots take incoming deliveries, stack them on shelves and also collect various items for outgoing shipments. There are a few rules for the Bots to follow such as, 1) Every 15 minutes they must take a 5 minute recharge break, 2) Any collision with a wall or another Bot requires the Bot to stop working and go through a diagnostic check, 3) Incoming deliveries must be collected and brought to a central distribution center within 5 minutes of it's arrival at the warehouse.

    I have a few other rules that will also be implemented as they come up. The only reason I am doing this is to provide myself with a exercise to learn programming AI with Behavior Trees. I'm also using A* 3.0 for Pathfinding and HOTWeen for Animation.

    So far Behave works very well. I just wish I had some working examples from some projects to see what others are doing and how they do it.

    One thing is clear to me - the smaller and more focused the Actions the better. It's great to be able to reuse Actions in different parts of the tree, but in order to do that successfully, you need to make the Actions really discrete. You wind up with lots of little Tick{ActionName}Action but it leads to flexibility and reuse in the Behavior Tree.

    Hope my insight helps. Let us know how it goes for you with Behave. The more dialogue, the better.

    Mitch
     
  21. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    767
    We use the charactermotor to move the mobs, and the behaviour tree has actions to set the inputvelocity of the character motor.
    We also extend the charactermotor to include turning over time.

    What you do in your actions is completely up to you. if you have some Steering and Navigation framework, then you can call it from the actions.
     
  22. Panajev

    Panajev

    Joined:
    Mar 26, 2012
    Posts:
    42
    Thanks for the reply Mitch, I found the tutorial on AIGameDev (http://aigamedev.com/insider/article/behavior-trees/) to be very good at introducing the concept of Behavior Trees and selling the concept's viability (it's a video I would keep open for a while in its own window). AngryAnt's from tree to code's video also helped me to clear some doubts I had about the specific use of Behave and to give some tips about how to best use the available documentation, but I would really like to see more documentation on the docs pages (especially considering that the actual code is quite well commented and when you click on decorators, actions, sequences, etc... inside Unity you get presented a very useful documentation).

    Definitely, I would say that the best way to learn how to use Behave is by doing it and talking about it with other people who are working on it, as I feel the learning curve involved in translating the patterns you can learn (from that Behavior Trees video for example) to actual code using Behave is perhaps one of its toughest challenges. Being a relatively young platform, Behave lacks a sort of agreed upon list of best practices and code resources, but I can understand the focus its creator is putting behind bug fixing it... I would rather place the bug fixing bit before adding new features if you asked me the priority I would like any middleware to focus on.


    This is a suggestion I am reading quite a bit in this thread, to make very focused and compact actions and decorators, to put a focus on making a library/collection of "tools" to be assembled in a tree later on. It's an iterative process of course, as you cannot possibly know, especially when you are new to Behavior Trees, all the actions you might need for example. You might start building your actions and decorators library from very basic and easy to conceptualize examples, but then you and your design team (which might be composed by... you :)) have to sit down and project the AI on paper, draw trees and subtrees, and come up with the actions and structures you will need. Then you go back to augment your toolbox of actions and more.

    To solve the Tick{ActionName}{Action|Decorator} explosion you might use the forwarding system (delegate objects), but I myself need a little more time to investigate it with Behave and JavaScript code.

    Right now, I am just getting my feet wet with Behave, exploring what I can do with it and learn to use it properly. I wanted to see how difficult it would be to assign this simple action to a sprite (well the same action to a batch of objects): "move X steps, turn around, move X steps, turn around, move X steps, etc...".
    The for loop was implemented with a decorator and I set in my actor class the direction which it should move towards and the actor class does the rest.

    Code (csharp):
    1.    
    2.  
    3. [...]
    4.  
    5. function InitAdvanceWithStepsDecorator (sender : Behave.Runtime.Tree, stringParameter, floatParameter:float, agent:IAgent, data) : BehaveResult {
    6.         if (needsInit) {
    7.             needsInit = false;
    8.            
    9.             moveDirection.x *= -1;
    10.             stepsDecorator = floatParameter;
    11.             //Debug.Log("This decorator should make its subtree loop " + stepsDecorator + " times...");
    12.         }
    13.         return BehaveResult.Success;
    14.     }
    15.    
    16.    
    17.     function TickAdvanceWithStepsDecorator (sender : Behave.Runtime.Tree, stringParameter, floatParameter:float, agent:IAgent, data) : BehaveResult {
    18.         stepsDecorator--;
    19.        
    20.         if (stepsDecorator <= 0) {
    21.             needsInit = true;
    22.             return BehaveResult.Failure;
    23.         }
    24.         else {
    25.             return BehaveResult.Success;
    26.         }
    27.     }
    28.    
    29.     function TickMakeStepAction (sender : Behave.Runtime.Tree) : BehaveResult {
    30.         //Debug.Log("Making a step... " + stepsDecorator + " steps left...");
    31.        
    32.         characterScript.MoveCharacter(moveDirection);
    33.        
    34.         return BehaveResult.Success;
    35.     }
    36.  
    37. [...]
    38.  
    39.  
    These are just baby steps, so nothing close to production code... but this agent script works when I attach it to my actor class. The actor object knows where it should move and it keeps going that way until it is told to go in a different direction.
    Behavior Trees are incredibly useful concepts in my opinion, from the understanding I have of them, but they require much more planning and research designing the tree on paper than it would appear and would appeal to some coders :). Not that it is a bad thing though.

    My code was already handling the animation, transitioning from Idle to Walking and back based on the actual movement of the character. A crude way of handling it, but again I aim to get a good grasp of things and then rewrite the code once I have a clear idea on what I want to do. Right now I am thinking about moving animation control into Behave as well although I am not sure about things such as tree frequency and all, just a feeling that keeping the two separate or indirectly separated might not be the best option since aside from being idle and walking, other states such as running, falling, or jumping are not doable by simply checking a motion vector and speed... well, truth to be told, they might be doable that way... they might also produce horrible spaghetti code too though :).

    I agree, thanks for your comments. Keep us posted, it is very helpful to hear fellow coders on this subject.
     
  23. SamFu

    SamFu

    Joined:
    May 14, 2012
    Posts:
    1
    I'm really enjoying using Behave so far. It's taken a couple of weeks to get my head around some AI concepts and things are shaping up nicely.

    One thing I haven't been able to figure out is how to move trees between collections? I see there's ability to rename and delete but not move.

    Is this possible in the current release of Behave? Is it a planned feature if not?
     
  24. Leiter Jakab

    Leiter Jakab

    Joined:
    Sep 25, 2010
    Posts:
    53
    Hi Emil!

    I'm working on my own steering behaviours for unity. Once it is fairly usable, I'd like to release it as a free tool. It is most likely very amateurish compared to UnitySteer, but it might still be helpful to some, or serve as an inspiration to do it better, or improve it.
    I'm planning to use Behave for my agents, and would include it in the example project.
    I would do this only if you allow me to do so. I would include it as you provide it, and would reference you as the creator, and your site in my readme file.
    Also if you have have a bit of time I'd like to ask you for some input on my trees. I wouldn't want to put a poor example of the use of Behave into the project.
    You can find a bit more information on my project here.
     
  25. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    767
    Does anyone know what context is for and how to use it?
     
  26. Leiter Jakab

    Leiter Jakab

    Joined:
    Sep 25, 2010
    Posts:
    53
    I would really like to know this as well. This and the correct use of parallel nodes.
     
  27. firesharkstudios

    firesharkstudios

    Joined:
    May 28, 2012
    Posts:
    2
    So, we are starting to use Behave in our game project and I have a few question that I couldn't find obvious answers to in the documentation...

    1) What is the purpose of Contexts and how are they used?

    2) What is the "object data" parameter passed in to each of the IAgent methods and how is it used?

    3) As I start to create a complex behavior tree with multiple child trees, having all the decorator and actions in a single class that implement IAgent seems less than ideal. What have others found with complex behavior trees is the best way to organize all the decorator and action implementations? Single big class that implements IAgent?
     
  28. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    I'm not really sure what you mean by sub-agents?
     
  29. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    I haven't tried it, but for the best chance of working, you should build your BTs with agent blueprints. That way the runtime will not do any .net reflection which most definitely will not work in flash.
     
  30. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Please use github issues for feature requests as well. They are easier for me to maintain and one bored saturday I even integrated listing them in my build script, so they're very visible ;)
     
  31. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Sure. That's a very nice and effective way of throttling your decision AI. Just keep the setup in mind when designing the tree - so as to not write trees which expect a certain consistent tick interval.
     
  32. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Everything you input in the tree designer is static.

    Instant means the component will not cause frame change. If you have five child components of a sequence and component 1-3 are marked instant, then on first tick (assuming all evaluate success), children 1-4 are all ticked (as child 3 does not cause a frame change, 4 is also ticked, but 4 then causes a frame change).

    Instant is quite useful for cheap conditionals.
     
  33. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    The action and decorator parameters are static. They allow the BT designer to put variance on the programmed handlers.
     
  34. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Hey there

    Yea built-in or standard libraries of actions and decorators is indeed something I've considered - pretty much from day one. I've just decided to focus on core features with the little time I have to work on this :)

    But hey - nothing stands in your way of building your own standard library - perhaps even sharing it on the asset store? :)

    Expression parameters has been suggested a few times. I've got an open github issue on it, but at the moment I don't view it as that high priority an item given the other items on that list. But it's definitely a good one!
     
  35. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    The primary advantage of decorators is that they can interrupt a child returning Running as well as have a child re-invoked after having completed (facilitating loops).

    However I really dislike the logic of how the return values of the decorator handlers are implemented, so I've got an alternative implementation on the drawing board.

    Unless you need interrupts and repeats I'd just stick with conditional actions.
     
  36. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Contexts are used to let the designer set some general tree state. While you could always have an action that sets some state on the agent, the context is set only in the BT designer. Contexts are set once and are persistent until re-set somewhere else in the tree.

    You can read the current context in your handlers - having them execute in whatever context the designer set.

    The data parameter is an optional parameter you can pass when you call myTreeReference.Tick. Behave will pass that parameter through to all handlers invoked as a result of that tick.

    An example of using this could be a tree designed to evaluate a target. You could pass in a reference to the target and the handlers would then cast correctly and use that target reference in their implementation.

    Regarding avoiding complex agent implementations, there are several ways of avoiding this - all regular OOP principles.

    You could implement a base agent with a set of handlers which you then derive from in more specialized agents.

    You could also choose to delegate certain handlers to other components via SetHandler calls.

    Lastly you could choose to write your own dispatcher mechanism in the general Tick and Reset methods.
     
  37. sfoust

    sfoust

    Joined:
    May 18, 2011
    Posts:
    26
    Hey All,

    I'm new to Behave and trying to setup and very simple example project to start working with.

    I've started from this video:

    http://youtu.be/wkDMTcUV5cU


    However, Behave seems to be silently failing on me.

    Here is the tree I'm using (built a debug version):



    Here is my code:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Behave.Runtime;
    4. using Tree = Behave.Runtime.Tree;
    5.  
    6. public class ChickenBtAgent : MonoBehaviour, IAgent {
    7.    
    8.     Tree tree;
    9.    
    10.     IEnumerable Start () {
    11.         Debug.Log("ChickenBtAgent Start");
    12.        
    13.         tree = BLChickenBehaviorLibrary.InstantiateTree(
    14.             BLChickenBehaviorLibrary.TreeType.AnimalCollection_ChickenTree,
    15.             this
    16.         );
    17.        
    18.         while(Application.isPlaying  tree != null) {
    19.             yield return new WaitForSeconds(1.0F / tree.Frequency);
    20.             AIUpdate();
    21.         }
    22.     }
    23.    
    24.     void AIUpdate() {
    25.         tree.Tick();
    26.     }
    27.    
    28.     public BehaveResult Tick (Tree sender, bool init) {
    29.         Debug.Log("ChickenBtAgent Tick");
    30.         BehaveResult result = BehaveResult.Success;    
    31.         return result;
    32.     }
    33.    
    34.     public void Reset (Tree sender) {
    35.        
    36.     }
    37.    
    38.     public int SelectTopPriority (Tree sender, params int[] IDs) {
    39.         int priority = (int)BLChickenBehaviorLibrary.PriorityType.PriorityIdel;
    40.        
    41.         switch(Random.Range(0,2)) {
    42.             case 0:
    43.                 priority = (int)BLChickenBehaviorLibrary.PriorityType.PriorityIdel;
    44.                 break;
    45.             case 1:
    46.                 priority = (int)BLChickenBehaviorLibrary.PriorityType.PriorityWander;
    47.                 break;
    48.             case 2:
    49.                 priority = (int)BLChickenBehaviorLibrary.PriorityType.PriorityEat;
    50.                 break;
    51.         }
    52.        
    53.         return priority;
    54.     }
    55.    
    56.     public BehaveResult TickIdelAction() {
    57.         Debug.Log("Idel Action");
    58.         return BehaveResult.Success;
    59.     }
    60.    
    61.     public BehaveResult TickWanderAction() {
    62.         Debug.Log("Wander Action");
    63.         return BehaveResult.Success;
    64.     }
    65.    
    66.     public BehaveResult TickEatAction() {
    67.         Debug.Log("Eat Action");
    68.         return BehaveResult.Success;
    69.     }
    70.    
    71.     public BehaveResult TickAlertAction() {
    72.         Debug.Log("Alert Action");
    73.         return BehaveResult.Success;
    74.     }
    75.    
    76.     public BehaveResult TickEvadeAction() {
    77.         Debug.Log("Evade Action");     
    78.         return BehaveResult.Success;
    79.     }
    80. }

    After building the Behave tree dll (debug version), compiling my code with no errors, then running the project, I get NO output to the console at all (not even from the Start method).

    Anyone see anything wrong with what I'm doing?

    Regards,

    Scott
     
  38. sfoust

    sfoust

    Joined:
    May 18, 2011
    Posts:
    26
    Forgot to include that, yes, I created a GameObject and added my script to it before running the project. ;)

    Scott
     
  39. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    I don't see anything immediately wrong with your agent code. The fact that you do not get the "ChickenBtAgent Start" message would suggest that this is not a Behave issue.

    With regards to the strange rendering of the priority labels, I'll take a look at it.
     
  40. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    Check the frequency setting in your Behavior Tree. By default its set to zero - no ticks! Quite a few of us were victimized by that. Change it to 1 if it is set to zero. (or whatever value you prefer)
     
  41. sfoust

    sfoust

    Joined:
    May 18, 2011
    Posts:
    26
    Thanks for the reply.

    Just noticed that I do get the following error from "BehaveMenu.cs":

    I'm running Unity version 3.5.2f2

    Could the above error have anything to do with my issue?

    Regards.
     
  42. sfoust

    sfoust

    Joined:
    May 18, 2011
    Posts:
    26
    @ MichStan Thanks much for the reply. I just checked my "frequency" setting . Mine is set to 5. I changed it to 1 and got the same result, Nothing at all.

    Would anyone be willing to try running my sample to code with tree pictured in my original pose? I'm just hoping to rule out that it's something to do with my system and setup.

    Regards,
     
  43. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    I noticed something odd to me about your code -- your Tick{ActionName}Action parameters are empty. I program in Unity JavaScript and you are in C#, but aren't we supposed to pass the tree as a parameter?

    Should

    Code (csharp):
    1. public BehaveResult TickEvadeAction() {
    2.  
    3.         Debug.Log("Evade Action");      
    4.  
    5.         return BehaveResult.Success;
    6. }
    7.  
    instead be

    Code (csharp):
    1. public BehaveResult TickEvadeAction(Tree sender) {
    2.  
    3.         Debug.Log("Evade Action");      
    4.  
    5.         return BehaveResult.Success;
    6.  
    7.     }
    8.  
    9.  
    Again, I'm in javascript and my actions look like this:

    Code (csharp):
    1.     function TickClaimDockCargoAction (sender : Behave.Runtime.Tree)
    2.     {
    3.         var cargo : Cargo = commandCenter.NextCargo(); // if no cargo on dock, cargo will return null
    4.         if (cargo)
    5.         {
    6.             destinations = cargo.Destinations;
    7.             forkLiftActions = cargo.ForkLiftActions;
    8.             return BehaveResult.Success;
    9.         }          
    10.         else  // cargo = null
    11.             return BehaveResult.Failure;       
    12.     }
    Not sure if this helps.

    Mitch
     
  44. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    That is a minor issue, expected and unrelated unfortunately.
     
  45. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    @sfoust:
    Re-iterating my initial response, all of this is irrelevant as your Start method is clearly not being invoked - suggesting this is not a Behave issue. I just quickly re-read your code and found out why:

    You have specified the wrong return type for your Start method. Co-routines return IEnumerator - not IEnumerable. Therefore Unity will not be looking for that method signature and will not invoke it. Correcting this typo should fix your problems.
     
  46. unikum

    unikum

    Joined:
    Oct 14, 2009
    Posts:
    58
    What is a good strategy to separate behaviours from the agent/player?

    What I'm trying to do is setting up a Behaviour Manager that every NPC has. That manager has several cues where behaviour trees can cue up and be run. Do the class that has IAgent have to be a monobehaviour or can I have a normal class do the ticking and actions?

    Maybe I'm thinking about this the wrong way. How should the separation between the behaviours and agents be done? I don't want behaviours to be tied to a specific type of agent.

    Thanks!

    edit: Or if I still have the behaviour tied to an agent, how can I separate the logic so the agent class isn't filled with hundreds of tick action functions?
     
    Last edited: Jun 15, 2012
  47. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    There are tons of ways to do this and the best fit really depends on the project. The IAgent implementer does not need to be MonoBehaviour derived. Only agent blueprints need to.

    Regarding splitting up init, tick and reset handlers, note that they don't necessarily have to live on the top-level class. So you could have a class hierarchy like this:

    MonoBehaviour, IAgent -> Basic agent -> Humanoid -> Enemy -> Marauder.

    At each level in that class hierarchy you could have action handlers - even marked as virtual so you could override them at a later stage if needed. That is how the agent blueprints work (with virtual handlers).


    <sidetracking a bit to talk about blueprints>

    Blueprints are extended from MonoBehaviour and require that you specify the supported trees when you set them up. The benefit is that the blueprint is pre-baked, so you will have zero reflection overhead on tree instantiation which will yield a performance boost. The above class hierarchy would look like this in stead:

    (MonoBehaviour, IAgent) MyBlueprint -> Basic agent -> Humanoid -> Enemy -> Marauder.

    Each action and decorator type used in the trees selected for MyBlueprint will then have handlers implemented as abstract methods in MyBlueprint for you to override (or re-override) at any point in the inheritance chain.

    </sidetracking a bit to talk about blueprints>


    So that is one example of leveraging the strengths of both OOP and BTs in a solution to avoid the giant class of doom while gaining flexibility. Another way to avoid it would be to use the set forward calls on your tree instance to have certain actions and decorators be handled on different classes. Or as you suggest have a non-MonoBehaviour IAgent implement all handlers and then have your own forwarding system between that and your MonoBehaviours.

    Personally I don't really like that last idea that much and prefer the inheritance and virtuals approach, but hey if you can think it up in the language, you can use it in Behave. Wire some dictionary of delegates to the tree instance? Sure. Writing special-case lambdas for certain handlers? Why not?
     
  48. sfoust

    sfoust

    Joined:
    May 18, 2011
    Posts:
    26
    Awh, rookie move on my part. :oops:
    Thanks so much for the reply. It's working great now. :D
     
  49. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Awesomeness :D
     
  50. TianWolf

    TianWolf

    Joined:
    Aug 20, 2011
    Posts:
    161
    I just started using Behave and every time I try to build library I get :

    System.SystemException: Error running gmcs: Cannot find the specified file

    What am I doing wrong?