Unity Community


Page 5 of 23 FirstFirst ... 3456715 ... LastLast
Results 81 to 100 of 448

  1. Posts
    38
    Quote Originally Posted by AngryAnt View Post
    @spaceshooter
    This means that you only have one tree within your current collection. You can add another tree to the collection by selecting it in the Behave browser and choosing "tree" in the "create" drop-down.

    Alternatively if you already have a subtree in your tree editor which you would like to transform into its own tree, so that it may be referenced by other trees, you may do so by right-clicking the topmost node of that subtree and clicking "form new tree".
    Aha, that did it.

    How do you recommend the code behind the tree be stored for re-usability (TickMoveAction() for example)?

  2. Keyboard operator

    Location
    Copenhagen, Denmark
    Posts
    2,929
    That is really all up to you. Behave gives you many options via its close tie-in with your code and its facilitation of references.

    For references, see Tree.Set*Forward at http://angryant.com/behave/documentation/tree. The close code tie-in enables you to for instance define some handler on a base class and then inherit from that class - adding more handlers and more specific functionality.
    Emil "AngryAnt" Johansen

    Game developer, AI specialist, Unity expert
    Freelancer, ex Unity Technologies

    AI in Unity, tips and tricks: http://angryant.com, http://twitter.com/angryant

    Coding bare-footed grants you extra CPU cycles!


    Want to play? http://angryant.com/freelance/
    Behave 2 is out! http://angryant.com/2013/12/23/Behave-2-2/
    Check out ReView!


  3. Posts
    38
    For high-level planners, a very low frequency is sometimes desired. I'm trying to set my frequency to 0.2 (once every five seconds); however, the following error pops up in Unity when I try to compile the Library (I also tested it for a float value greater than 1, and had the same result):

    Compile Error
    Internal compiler error

    Strangely, no error shows up in the debug log.


    Also, how would the system behave if you use a sub-tree with a different frequency value?

  4. Keyboard operator

    Location
    Copenhagen, Denmark
    Posts
    2,929
    @chirhotec
    The compile error you are getting is a known issue which is fixed in the next release of Behave. the current workaround is to use integral frequency values:

    https://github.com/AngryAnt/Behave-release/issues/8

    As mentioned in the tree documentation, the frequency value has no direct impact on the predefined Behave runtime. It is merely there for designer convenience. I believe I show an example of how to make use of it in one of the videos:

    http://angryant.com/behave/documentation/tree
    Emil "AngryAnt" Johansen

    Game developer, AI specialist, Unity expert
    Freelancer, ex Unity Technologies

    AI in Unity, tips and tricks: http://angryant.com, http://twitter.com/angryant

    Coding bare-footed grants you extra CPU cycles!


    Want to play? http://angryant.com/freelance/
    Behave 2 is out! http://angryant.com/2013/12/23/Behave-2-2/
    Check out ReView!


  5. Posts
    38
    @AngryAnt: Thanks for your timely response yesterday; And I'll try to be more diligent in checking the issues next time around.



    I've been reading through all the Arges tutorials and related stuff on AI Game Dev, but am still stuck conceptually on what I'd think would be a relatively common task.

    I'd like to have the NPC AI switch between behavior subtrees based on proximity to the player. For a simple example, I have a character with two main behaviors, Idle and Presentation, neither of which are just one action (though I've represented Presentation as just an action, until I expand it later on). When the player moves out of range, the NPC will go into its Idle behavior. When the player moves into range, the NPC should go into the Presentation behavior. Either way, if the proximity condition every changes, that subtree should abort and switch the other subtree.

    Images of all of these tree are attached, below.

    I think these should be combined with a Selector, since only one of them should run. In this example, a sequence would work since you are always switching between two disjoint subtrees, but it wouldn't expand well for future added behaviors.

    I've come across three possible solutions to the problem:

    Check Proximity in every Action

    Arges System's tutorial (shift in focus section) suggests checking the proximity condition within the Tick of the Action that may need to abort. I'm sure this would work, but I haven't tried this approach because it seems this is something that should be handled by the tree structure and because it makes it harder to maintain / reuse the code once you start adding those checks all over the place.

    Decorator Approach

    For the decorator approach, I created a simple "EnsureProximity" decorator that returns Success if the player is within range, and Failure if the player is not within range. I figured I could use this for both subtrees by inverting the result when the actions should run only if the player is out of range.


    When I run it, TickEnsureProximityDetector detects the user is not within range, returns failure and doesn't go into the subtree. However, that is considered Successful to the selector, so it thinks its done with everything, and restarts the tree.

    I also tested it with a Sequence instead of a Selector, however, it didn't work either, but for slightly different reasons. The first EnsureProximity successfully prevents the subtree from running. However the second returns Failure in the Tick method, so its subtree is not ticked. It then returns Success (task completed), but that is inverted before the Sequence sees it, making the sequence fail out.

    I guess I don't understand why the decorators / inverters work the way they do; or at least not how to effectively apply them to perform this task.

    Assertions via Parallel Combiner

    AiGameDev.net suggests on the BT video tutorial and on their page about parallels, that parallels are good for this kind of assertion checking.

    I tried that method too, but couldn't get it to work properly either. Unfortunately, I can't remember why anymore, my brain is a little fried and I have to leave the office.

    I think it had to do with the EnsureProximity action only being ticked the first time the parallel is ticked. After it passes that first time, the subtree is ticked and it has to complete all of its work before the EnsureProximity will be checked again. (I guess I was expecting EnsureProximity to tick every time that sub tree is ticked).


    Anyways, if anyone has any suggestion on how to fix either of these approaches (or both, as a learning example), it would be greatly appreciated.
    Attached Images     

  6. Keyboard operator

    Location
    Copenhagen, Denmark
    Posts
    2,929
    Yea decorators + inversion + tick return value works differently than it does for actions (which is why I have separate tick handlers for actions and decorators). You would have to do the inversion in the implementation - not on the component. If you want control over it via the tree editor, you could make the behaviour of the implementation dependent on the decorator parameters (you can specify a string and float parameter in the inspector). However the simplest solution would probably be to just have a WithinRange and NotWithinRange implementation.

    To have your tree looping - that is re-start once it finishes, you need to instruct it to do so from your implementation. Here's an example of how that could be done:

    Code:  
    1.     Tree m_Tree;
    2.    
    3.    
    4.     IEnumerator Start ()
    5.     {
    6.         m_Tree = BLMyBehaveLibrary.InstantiateTree (BLMyBehaveLibrary.TreeType.MyCollection_MyTree, this);
    7.         while (Application.isPlaying)
    8.         {
    9.             yield return new WaitForSeconds (1.0f / m_Tree.Frequency);
    10.             AIUpdate ();
    11.         }
    12.     }
    13.    
    14.    
    15.     void AIUpdate ()
    16.     {
    17.         if (m_Tree.Tick () != BehaveResult.Running)
    18.         {
    19.             Debug.Log ("Reset");
    20.             m_Tree.Reset ();
    21.         }
    22.     }

    The reason why your parallel efforts are not working out is because you think of it in terms of sequences and selectors. If you want a child of a parallel to be constantly ticked, that child should be returning the result of Running. Once you want a child to influence the parallel towards terminating, that child should return Success or Failure.

    If you want a single child to be able to terminate a parallel, you should configure that parallels termination to be dependent on one child returning - not all. In your specific case, your parallel conditions should return Running until the point where they are no longer valid. Then they should return Failure or Success - whatever makes sense. Your parallel should then be set up to terminate once a single child terminates. This will result in parallel termination once any of the conditions or the tasks returns non-running.
    Emil "AngryAnt" Johansen

    Game developer, AI specialist, Unity expert
    Freelancer, ex Unity Technologies

    AI in Unity, tips and tricks: http://angryant.com, http://twitter.com/angryant

    Coding bare-footed grants you extra CPU cycles!


    Want to play? http://angryant.com/freelance/
    Behave 2 is out! http://angryant.com/2013/12/23/Behave-2-2/
    Check out ReView!


  7. Posts
    38
    My current implementation of AIUpdate (what you provided in the Tree to Code video) already repeats. I just assumed that if you ticked a completed tree it restarts.

    The fix you suggested to the parallel implementation made a lot of sense, and cleaned up some of my understanding about the system. The only issue now is that on each given tick, all children are ticked even if a tick to the left is completed (and the component completion is set to One). Maybe this could be an option, so that parallels can be used for assertions?

    As for the decorator approach, I created two decorators to avoid the added complications of inverting the results. And I was pleasantly surprised to see that the decorator is ticked every time any descendant block is ticked. However, the underlying issue still exists: With no way for a decorator to return Failure by itself, I don't see how it can be used for assertions.

  8. Keyboard operator

    Location
    Copenhagen, Denmark
    Posts
    2,929
    I'll take the suggested option for parallels into consideration. Thanks for bringing it up. And yes, validation does indeed happen *after* all children have been ticked. In Behave 1.3, I've clarified the Parallel description some more.

    Decorators are indeed not suited for assertions, but rather interrupts and loops. Use sequenced actions for assertions.

    Glad you're finding the product useful
    Emil "AngryAnt" Johansen

    Game developer, AI specialist, Unity expert
    Freelancer, ex Unity Technologies

    AI in Unity, tips and tricks: http://angryant.com, http://twitter.com/angryant

    Coding bare-footed grants you extra CPU cycles!


    Want to play? http://angryant.com/freelance/
    Behave 2 is out! http://angryant.com/2013/12/23/Behave-2-2/
    Check out ReView!


  9. Posts
    38
    Very useful indeed. And thanks for checking the thread and helping out so much!

    Quote Originally Posted by Behave's In-Editor Decorator Documentation
    The Decorator id and its parameters will be given in this call (if applicable) and if this is the first call to the Decorator (and not a return call through a Running state), the init boolean will be set to true (if applicable) - otherwise false.
    Does this mean that the Init {Name} Decorator function should only be called the first time that its reached in a branch (unless it exits, and the branch is reached again)? Because it seems like the decorators are being reinitialized if the children complete successfully.

    In my case I want a Decorator that will repeat an action over time. I initialize the time in the InitRepeatForTimeDecorator and return success. In the TickRepeatForTimeDecorator, I check to see if the time has lapsed, returning Success if it has, and Running if not.

    However, when the children runs and returns Success, it triggers the whole thing to restart. So the RepeatForTime gets reinitialized, the timer gets reset, and it never breaks out.

    Here's my Decorator code, for whats its worth:

    Code:  
    1.    public BehaveResult InitRepeatForTimeDecorator (Tree sender,
    2.         string timer, float time, IAgent agent, object data)
    3.     {
    4.         endTimes[timer] = Time.time + time;
    5.        
    6.         DebugPrintTick("Init", "Decorator", "RepeatForTime",
    7.             timer + " from " + Time.time + " to " + endTimes[timer]);
    8.         return BehaveResult.Success;
    9.     }
    10.    
    11.     public BehaveResult TickRepeatForTimeDecorator (Tree sender,
    12.         string timer, float floatParameter, IAgent agent, object data)
    13.     {
    14.         DebugPrintTick("Tick", "Decorator", "RepeatForTime",
    15.             timer + " ? " + Time.time + " > " + endTimes[timer]);
    16.  
    17.         if (endTimes.ContainsKey(timer))
    18.         {
    19.            
    20.             if (Time.time < endTimes[timer])
    21.                 return BehaveResult.Running;
    22.             else
    23.                 return BehaveResult.Success;
    24.         }
    25.         else        
    26.         {
    27.             return BehaveResult.Failure;
    28.         }
    29.        
    30.     }

    This could be accomplished by adding code to the action that also checks the timer, or adding another action that runs in parallel and stalls until the timer is finished. However, both of those seem like its adding unnecessary complexity and making the components less reusable.

    Are there any concrete examples of using decorators to accomplish some standard operations, like Repeating child for a time period, delay the return of child until time has lapsed (holding, without repeating), allowing child to run for a maximum amount of time? (Also, checking for a flag to be triggered, or running a certain number of times, but those are just variations on the above, replacing time with a different condition)


  10. Posts
    38
    I think I actually figured out most of these, though some of them took an extra block to get the functionality just right.

    But I am still curious about whether that issue with the Decorator restarting is a bug, or by design.

  11. Keyboard operator

    Location
    Copenhagen, Denmark
    Posts
    2,929
    This is an (untested) example of how I would do a simple repeater:

    Code:  
    1. public BehaveResult InitRepeatDecorator (Tree sender, string stringParameter, float floatParameter, IAgent agent, object data)
    2. {
    3.     if (repeaters[stringParameter]++ > floatParameter)
    4.     {
    5.         return BehaveResult.Failure;
    6.     }
    7. }
    8.  
    9.  
    10. public BehaveResult TickRepeatDecorator (Tree sender, string stringParameter, float floatParameter, IAgent agent, object data)
    11. {
    12.     return BehaveResult.Running;
    13. }
    14.  
    15.  
    16. public void ResetRepeatDecorator (Tree sender, string stringParameter, float floatParameter, IAgent agent, object data)
    17. {
    18.     repeaters[stringParameter] = 0;
    19. }

    A bit later I could look at how your time based repeater could be adapted to work similarly to this.
    Emil "AngryAnt" Johansen

    Game developer, AI specialist, Unity expert
    Freelancer, ex Unity Technologies

    AI in Unity, tips and tricks: http://angryant.com, http://twitter.com/angryant

    Coding bare-footed grants you extra CPU cycles!


    Want to play? http://angryant.com/freelance/
    Behave 2 is out! http://angryant.com/2013/12/23/Behave-2-2/
    Check out ReView!

  12. Keyboard operator

    Location
    Copenhagen, Denmark
    Posts
    2,929
    Moved to the new Assets forum section.
    Emil "AngryAnt" Johansen

    Game developer, AI specialist, Unity expert
    Freelancer, ex Unity Technologies

    AI in Unity, tips and tricks: http://angryant.com, http://twitter.com/angryant

    Coding bare-footed grants you extra CPU cycles!


    Want to play? http://angryant.com/freelance/
    Behave 2 is out! http://angryant.com/2013/12/23/Behave-2-2/
    Check out ReView!


  13. Posts
    40
    Hi.
    Thanks a lot for this AA, I'm reimplementing the IA of my game from scratch with this and everything is looking much cleaner and extensible.
    Still struggling on getting a few behaviours done but that's only my inexperience with BTrees.

    I have a question about the interface.
    How can I recreate a link (with the objective of reordening childs) without having to erase nodes ?

  14. Keyboard operator

    Location
    Copenhagen, Denmark
    Posts
    2,929
    Hey Minassian. Great to hear you find good use of my tool. Connection rearranging is not very easy to spot in the current version of Behave -this is fixed in 1.3.

    To rearrange connections in 1.2, select the output node with the outgoing connections you wish to rearrange and then in the inspector, select a connection in the connection list and hit the tiny up-arrow above the connection list to move it upwards in the list.
    Emil "AngryAnt" Johansen

    Game developer, AI specialist, Unity expert
    Freelancer, ex Unity Technologies

    AI in Unity, tips and tricks: http://angryant.com, http://twitter.com/angryant

    Coding bare-footed grants you extra CPU cycles!


    Want to play? http://angryant.com/freelance/
    Behave 2 is out! http://angryant.com/2013/12/23/Behave-2-2/
    Check out ReView!


  15. Posts
    40
    Ah missed it !
    Easy enough, thx.

    I have a few design questions but I'm gonna read the hole thread to avoid reasking.
    Cheers.


  16. Posts
    40
    I can't believe I wrote a huge post and lost it because this forums does not allow to open a link in a tab.
    Anyway, catarsis out of the way, here I go again.

    I think I have a similar problem to chirhotec, I'm still figuring out how the best way to implement events.
    Checking proximity in every action is out of the question for me. I woulnd't know how to implement it in a maintanable way.
    Haven't digged seriously into the decorator approach yet.
    Here's my shot at assertions via parallel combiner.
    I'm trying to make a vehicle wander around the map, and escort another vehicle when it enters its radius.
    If this other vehicle stops being escortable for some reason, it'll return back to wandering.
    Parallel is configured with 'One' component completion, and 'Success' child completion.



    This is the pseudo code of the escorting methods:
    Code:  
    1. // This method's responsibility is to look for escortable targets in receivers area of sight.
    2. // Any target receiver may have is reseted.
    3. // This method cannot fail, only success and running results will be returned.
    4. public BehaveResult TickLookForEscortableTargetAction(Tree sender)
    5. {
    6.     if(target != null) resetTarget();
    7.     if(TickSeeEscortableUnitAction(sender) == BehaveResult.Success)
    8.         return BehaveResult.Success;
    9.     else
    10.         return BehaveResult.Running;
    11. }
    12.  
    13. // Returns wether the receiver sees any escortable units.
    14. // If return value is a sucess, then receivers target will be set to the escortable target seen.
    15. // If a failure is returned, then target is not changed.
    16. // This never returns a running result.
    17. public BehaveResult TickSeeEscortableUnitAction(Tree sender)
    18. {
    19.     if(target != null && target.canBeEscorted()) return BehaveResult.Success;
    20.     newTarget = getNearEscortableUnit();
    21.     if(newTarget == null)
    22.         return BehaveResult.Failure;
    23.     else
    24.     {
    25.         target = newTarget;
    26.         return BehaveResult.Success;
    27.     }
    28. }

    So its basically the same method but conceptually changed the result value, reusing the code.
    By returning the current target if its escortable in TickSeeEscortableUnitAction() I ensure not to look it up twice when going from wandering to escorting.

    This works pretty well so far, but I'm not sure yet how extensible it is to more complex behaviours, or if it's the most correct way of doing it.
    I don't like the fact of having two nodes (functions) for the same thing, I feel that somehow that would need to be delegated to the tree.
    Sugestions welcome.
    Last edited by Minassian; 02-02-2011 at 01:44 PM.


  17. Posts
    38
    @AA, meant to ask this earlier, is this a good place for general discussion of how to implement BTs with Behave, and best practices, or should we split to a different thread, and keep this one focused on release notes?

    @Minassian, having only begun doing game AI in the last couple weeks I'm no expert, but here's how I did mine with decorators:



    Note that the use of the series component depends mostly on where this component fits in with the rest of the Behavior tree. Since the two branches are mutually exclusive, and these decorators never return Success (either Failure or Running), any of the options will work most of the time.

    Both decorators work essentially the same way. You provide a flagName bool value to check against, and they return Running while that boolean is set to true or false. After the boolean switches to false or true, the decorator halts the child by returning Failure (which is regarded as success to the decorator's parent, btw). You can do the actual checking of that boolean value somewhere else, either in the update / fixedupdate function, external function calls to your object, etc.

    Here is the returned result based on what the decorator and child return each tick. Note that in my code, I actually call these "RepeatWhileFalse" and "RepeatWhileTrue". This makes it more explicit that if your child returns Success or Failure, and the decorator is still Running, your child will automatically restart, even if you only mean it to be a one time thing.


    The WhileTrue is similar with the conditions reversed.

    Additionally, when the child repeats, the decorator is actually restarted as well. For this reason (and because I do the variable checking / setting in other places), I don't initialize the flag to any value in the Init<X>Decorator function, unless the flag doesn't yet exist. Instead, if you need to ensure a value is set to true or false before that section is called, use SetFlag / ClearFlag Actions in your BT.

    If, instead of repeating the child, you wanted to do something where you run the child only once and stall until the flag is tripped, you'd need something like this:



    You can see the implementation in the attached code file, BaseAgent.cs. The main things to note are: (1) I had to rip out a lot of my project code, and I didn't test it afterward, so you'll need to do some clean up to make sure it compiles. (2) To keep things generalized, I use a dictionary to keep track of flagName / boolean value pairs, and passed in the string name as a decorator. (3) Since there are a lot of decorators / actions that I reuse, I created the BaseAgent to store common pieces. You'll need to create an agent that subclasses it and adds the extra functionality for that particular agent.

    For the last week or two I've been meaning to write up a tutorial on what I've learned about implementing things with BTs and decortors using Behave, but I've been swamped lately, and at the earliest, I wont have time until this weekend. In the mean time, I hope this helps. And thanks for the enjoyable diversion from work
    Attached Files
    Last edited by chirhotec; 02-02-2011 at 02:41 PM.

  18. Keyboard operator

    Location
    Copenhagen, Denmark
    Posts
    2,929
    @chirhotec:
    I think as long as people check the available resources first - the aiGameDev video, this thread and such before posting, general BT design questions are just fine in here.
    Emil "AngryAnt" Johansen

    Game developer, AI specialist, Unity expert
    Freelancer, ex Unity Technologies

    AI in Unity, tips and tricks: http://angryant.com, http://twitter.com/angryant

    Coding bare-footed grants you extra CPU cycles!


    Want to play? http://angryant.com/freelance/
    Behave 2 is out! http://angryant.com/2013/12/23/Behave-2-2/
    Check out ReView!


  19. Location
    Medellin, Colombia
    Posts
    448
    I have a workflow question.

    Say there's more than one person working on a single behave library (more than 1 AI designer making trees and collections). How can I keep the library on sync on the asset server so that the server version reflects all of the changes made by the designers?

    I have't found a good way around this since the library is not a text asset so it won't let me diff or merge.
    Director of Development
    C2 Estudio
    www.c2estudio.com


  20. Posts
    1

    Error running gmcs: Cannot find the specified file

    I was trying to use behave 1.2 in unity 3.1 (with iPhone basic license). I created one tree in a collection by following the video tutorial (http://angryant.com/wp-content/uploa...om-scratch.mov). Everything went well, but when I clicked the "building library debug" button, I got the following error:

    System.SystemException: Error running gmcs: Cannot find the specified file
    at Mono.CSharp.CSharpCodeCompiler.CompileFromFileBatc h (System.CodeDom.Compiler.CompilerParameters options, System.String[] fileNames) [0x00000] in <filename unknown>:0
    at Mono.CSharp.CSharpCodeCompiler.CompileFromSourceBa tch (System.CodeDom.Compiler.CompilerParameters options, System.String[] sources) [0x00000] in <filename unknown>:0
    at Mono.CSharp.CSharpCodeCompiler.CompileAssemblyFrom SourceBatch (System.CodeDom.Compiler.CompilerParameters options, System.String[] sources) [0x00000] in <filename unknown>:0
    at System.CodeDom.Compiler.CodeDomProvider.CompileAss emblyFromSource (System.CodeDom.Compiler.CompilerParameters options, System.String[] fileNames) [0x00000] in <filename unknown>:0
    at Behave.Editor.Compilers.Unity.Compile () [0x00000] in <filename unknown>:0
    UnityEngine.Debug:LogError(Object)
    Behave.Runtime.Resources:LogError(String)
    Behave.Editor.Compilers.Unity:Compile()
    Behave.Editor.Compiler:Run()
    Behave.Editor.CompileroCompile(IBehaveAsset, Boolean)
    Behave.Editor.Compiler:Compile(IBehaveAsset, Boolean)
    BehaveMenu:Compile(Boolean) (at Assets/Behave/Editor/BehaveMenu.cs:55)
    BehaveMenu:Compile() (at Assets/Behave/Editor/BehaveMenu.cs:31)
    BehaveAssetEditor:Update() (at Assets/Behave/Editor/BehaveAssetEditor.cs:34)
    UnityEditor.EditorApplication:Internal_CallUpdateF unctions()


    I searched this thread and found that andy0305 and longshot had got the same problem, Could you tell me how you resolved it? thanks.

Page 5 of 23 FirstFirst ... 3456715 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •