obj-behaviortree is an implementation of a behavior tree for iOS. Supported tasks include:
- Selector
- Sequence
- Concurrent
- Condition
Behavior trees can be built programatically, or by reading from a JSON file.
The project currently builds and runs successfully with:
- Xcode 4.5
- iOS 5.0+
Clone the repository to a location on your machine, then:
$ git submodule init
$ git submodule update
Open BehaviorTree.xcworkspace
Test scenarios are available in the BehaviorTree project, which can be run in the usual way (CMD+U).
A demo project is available in the BehaviorTreeDemo project.
A behavior tree can be built from a JSON representation:
{"type":"Selector","children":[
{"type":"ShouldFlee","task":
{"type":"Flee"}
},
{"type":"ShouldSeek":"task":
{"type":"Seek"}
}
]}
The JSON is read by AOBehaviorReader which builds an instance of AOBehaviorTree:
NSString *json;
...
AOBehaviorReader *reader = [[AOBehaviorReader alloc] init];
AOBehaviorTree *behavior = [reader buildTreeWithFile:json];
The reader supports setting properties on task instances:
{"type":"MyAction","someBoolean":true}
If you want to set a property of type "Class", you can use the syntax:
{"type":"Flee","fromClassType":"class:MyEnemy"}
Task types read in from JSON are used to instantiate an objective-c class. To avoid polluting the JSON with class prefixes, you can register your own class prefixes that will be automatically searched when attempting to instantiate a task.
For example, if you register the prefix "AB" with the BehaviorReader:
AOBehaviorReader *reader = [[AOBehaviorReader alloc] init];
[reader registerPrefix:@"AB"];
and your JSON contains the task:
{"type":"MyTask"}
then the BehaviorReader will first attempt to find a class named "MyTask", and then if that class does not exist it will attempt to find a class named "ABMyTask".
Logging can be enabled by setting preprocessor macro flags on the BehaviorTree target.
BTree_NSLog
Logs to console window using standard NSLog
BTree_NSLogger
Logs to an NSLogger client using the NSLogger client library, which is much faster than using NSLog.