This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
dragengine:modules:dragonscript:behavior_statemachine [2025/03/11 18:52] – [Instance Counts] dragonlord | dragengine:modules:dragonscript:behavior_statemachine [2025/05/09 19:04] (current) – dragonlord | ||
---|---|---|---|
Line 1: | Line 1: | ||
{{tag> | {{tag> | ||
<WRAP youarehere> | <WRAP youarehere> | ||
- | [[: | + | [[: |
- | </ | + | |
- | + | ||
- | * [[behaviors_use_cases|Behaviors Explained: By Use-Case]] | + | |
- | * [[behaviors_a_to_z|Behaviors Explained: From A to Z]] | + | |
- | + | ||
- | ====== ECBehaviorStateMachine ====== | + | |
- | + | ||
- | <WRAP center 100%> | + | |
- | <WRAP center box 450px> | + | |
- | {{youtube> | + | |
- | <WRAP centeralign> | + | |
- | </ | + | |
- | </ | + | |
- | + | ||
- | Behavior element behavior adding # | + | |
- | + | ||
- | Loads state machine from file (*.desm) and creates an # | + | |
- | + | ||
- | This behavior can be used in different ways depending on the needs. | + | |
- | + | ||
- | Single state machine is the most simple solution where only one state machine is used. For many situations this is enough and is the most simple solution to use. Add one **ECBehaviorStateMachine** with no ID to the element and as many other behaviors adding actions and conditions as required. Set the // | + | |
- | + | ||
- | This is an example code for such a setup: | + | |
- | < | + | |
- | class MyElementClass extends BehaviorElementClass | + | |
- | | + | |
- | var ECBehaviorStateMachine smbehavior = ECBehaviorStateMachine.new(this) | + | |
- | smbehavior.getPath().setValue("/ | + | |
- | + | ||
- | // here you can add now behaviors assigining actions and conditions for | + | |
- | // the state machine to use | + | |
- | ... | + | |
- | + | ||
- | // add listeners to behaviors to send events to the state machine | + | |
- | var ECBehaviorTwoStateAnimated animated = ... | + | |
- | animated.addActionConditionFactory(MyEventListener.Factory.new(smbehavior)) | + | |
- | end | + | |
- | + | ||
- | // two state listeners used to send events | + | |
- | class MyEventListener extends ECBehaviorTwoStateAnimated.DefaultListener | + | |
- | class Factory implements ECBehaviorTwoStateAnimated.ActionConditionFactory | + | |
- | | + | |
- | + | ||
- | | + | |
- | this.stateMachine = stateMachine | + | |
- | end | + | |
- | + | ||
- | | + | |
- | return MyEventListener.new(stateMachine.instance(instance.getElement())) | + | |
- | end | + | |
- | end | + | |
- | + | ||
- | | + | |
- | + | ||
- | | + | |
- | this.stateMachine = stateMachine | + | |
- | end | + | |
- | + | ||
- | | + | |
- | stateMachine.runEvent(" | + | |
- | end | + | |
- | + | ||
- | | + | |
- | stateMachine.runEvent(" | + | |
- | end | + | |
- | end | + | |
- | end | + | |
- | </ | + | |
- | + | ||
- | **Action and Condition Factory** | + | |
- | + | ||
- | You can assign # | + | |
- | + | ||
- | The example below shows how to use a factory to add a condition checking for a trigger and an action manipulating a trigger. | + | |
- | < | + | |
- | class MyElementClass extends BehaviorElementClass | + | |
- | | + | |
- | var ECBehaviorStateMachine smbehavior = ECBehaviorStateMachine.new(this) | + | |
- | smbehavior.getPath().setValue("/ | + | |
- | + | ||
- | // add factory to create actions and conditions later on. this example uses | + | |
- | // a code block for simplicity. using classes implementing ActionConditionFactory | + | |
- | // is preferred since it allows to reuse factories across element classes. | + | |
- | smbehavior.setActionConditionFactory( block ECBehaviorStateMachine.Instance instance | + | |
- | // add condition evaluating to true if " | + | |
- | // the condition can be used in the state machine using the name " | + | |
- | | + | |
- | " | + | |
- | + | ||
- | // add action pulsing (fire and immediately reset) " | + | |
- | // the action can be run in the state machine using the name "hurt playe" | + | |
- | | + | |
- | end ) | + | |
- | end | + | |
- | end | + | |
- | </ | + | |
- | + | ||
- | {{tag>dragonscript | + | |
- | <WRAP youarehere> | + | |
- | [[:start|Start Page]] >> [[main|DragonScript Scripting Language]] >> [[abstractions# | + | |
</ | </ | ||
Line 124: | Line 24: | ||
This behavior can be used in different ways depending on the needs. | This behavior can be used in different ways depending on the needs. | ||
- | _Single | + | // |
This is the most simple solution where only one state machine is used. For many situations this is enough and is the most simple solution to use. Add one ECBehaviorStateMachine with no ID to the element and as many other behaviors adding actions and conditions as required. Set the '' | This is the most simple solution where only one state machine is used. For many situations this is enough and is the most simple solution to use. Add one ECBehaviorStateMachine with no ID to the element and as many other behaviors adding actions and conditions as required. Set the '' | ||
Line 130: | Line 30: | ||
See [[# | See [[# | ||
- | _Multiple | + | // |
You can add multiple instances of ECBehaviorStateMachine to the element to load and use multiple state machines. This can be for using multiple state machines together to model complex logic. In this situation behaviors assigining actions and conditions do add them to all instances of ECBehaviorStateMachine. This is usually not a problem since the state machines are written to use only the actions and conditions making sense to be used. | You can add multiple instances of ECBehaviorStateMachine to the element to load and use multiple state machines. This can be for using multiple state machines together to model complex logic. In this situation behaviors assigining actions and conditions do add them to all instances of ECBehaviorStateMachine. This is usually not a problem since the state machines are written to use only the actions and conditions making sense to be used. | ||
Line 144: | Line 44: | ||
===== path ===== | ===== path ===== | ||
Set path to state machine file to load. | Set path to state machine file to load. | ||
- | * Full name: '' | + | * Full name: '' |
* Type: string | * Type: string | ||
* Default Value: empty string | * Default Value: empty string | ||
* Expected File Type: '' | * Expected File Type: '' | ||
- | * Example (*.deeclass) <code xml>< | + | * Example (*.deeclass) <code xml>< |
+ | |||
+ | ===== debug ===== | ||
+ | Debug mode prefix. If not empty string enables debug mode with prefix to locate log messages easily. | ||
+ | * Full name: '' | ||
+ | * Type: string | ||
+ | * Default Value: empty string | ||
+ | * Example (*.deeclass) <code xml>< | ||
===== Events ===== | ===== Events ===== | ||
This behavior has no events. | This behavior has no events. | ||
+ | |||
+ | ====== Behavior Tree Actions ====== | ||
+ | |||
+ | This behavior adds these behavior tree actions if behavior tree is present. If behavior has non-empty identifier replace '' | ||
+ | |||
+ | ===== stateMachine.set ===== | ||
+ | |||
+ | Set one or more state machine parameters. | ||
+ | |||
+ | ^Parameter^Value^Description^ | ||
+ | |reset| |Set state machine root state as current state| | ||
+ | |state|string|Set state machine state to state with identifier matching string value| | ||
+ | |||
+ | This is an example of using this action: | ||
+ | <code xml> | ||
+ | <action name=' | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ===== stateMachine.event ===== | ||
+ | |||
+ | Run event on state machine. | ||
+ | |||
+ | ^Parameter^Value^Description^ | ||
+ | |id|string|Identifier of event to run| | ||
+ | |||
+ | This is an example of using this action: | ||
+ | <code xml> | ||
+ | <action name=' | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ===== stateMachine.check ===== | ||
+ | |||
+ | Check one or more state machine parameters. Action succeeds if all parameter value matches their respective state machine parameter otherwise action fails. This action is typically used as first action in a sequence to run the sequence only if a state machine parameter matches (or not). | ||
+ | |||
+ | ^Parameter^Value^Description^ | ||
+ | |state|string|Current state identifier matches string value| | ||
+ | |state.not|string|Current state identifier does not match string value| | ||
+ | |state.starts|string|Current state identifier starts with string value| | ||
+ | |state.starts.not|string|Current state identifier does not start with string value| | ||
+ | |state.ends|string|Current state identifier ends with string value| | ||
+ | |state.ends.not|string|Current state identifier does not end with string value| | ||
+ | |state.contains|string|Current state identifier contains string value| | ||
+ | |state.contains.not|string|Current state identifier does not contain string value| | ||
+ | |wait| |If present action returns BTResult.running instead of BTResult.failed to wait until the checks are all fulfilled| | ||
+ | |||
+ | This is an example of using this action: | ||
+ | <code xml> | ||
+ | < | ||
+ | <action name=' | ||
+ | < | ||
+ | </ | ||
+ | <!-- actions here run only if state machine is in the " | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====== Behavior Tree Conditions ====== | ||
+ | |||
+ | This behavior adds these behavior tree conditions if behavior tree is present. If behavior has non-empty identifier replace '' | ||
+ | |||
+ | ===== stateMachine.check ===== | ||
+ | |||
+ | Check one or more state machine parameters. Conditions returns true if all parameter value match their respective state machine parameter. This condition is typically used to run an action or sequence of actions as long as state machine conditions are true. | ||
+ | |||
+ | ^Parameter^Value^Description^ | ||
+ | |stateMachine.state|string|Current state identifier matches string value| | ||
+ | |stateMachine.state.not|string|Current state identifier does not match string value| | ||
+ | |stateMachine.state.starts|string|Current state identifier starts with string value| | ||
+ | |stateMachine.state.starts.not|string|Current state identifier does not start with string value| | ||
+ | |stateMachine.state.ends|string|Current state identifier ends with string value| | ||
+ | |stateMachine.state.ends.not|string|Current state identifier does not end with string value| | ||
+ | |stateMachine.state.contains|string|Current state identifier contains string value| | ||
+ | |stateMachine.state.contains.not|string|Current state identifier does not contain string value| | ||
+ | |||
+ | This is an example of using this condition: | ||
+ | <code xml> | ||
+ | <action name=' | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
====== Required Behaviors ====== | ====== Required Behaviors ====== | ||
Line 160: | Line 151: | ||
====== Optional Behaviors ====== | ====== Optional Behaviors ====== | ||
- | This behavior | + | * [[behavior_behaviortree|ECBehaviorBehaviorTree]]: |
====== Persistency ====== | ====== Persistency ====== | ||
Line 181: | Line 172: | ||
====== Element Class Example ====== | ====== Element Class Example ====== | ||
- | Example of the _Single | + | Example of the // |
< | < | ||
Line 229: | Line 220: | ||
</ | </ | ||
- | Example of the _Multiple | + | Example of the // |
< | < | ||
Line 261: | Line 252: | ||
The above example loads and runs two state machines. The first one is running specific state machine. The second state machine provides two separate state machines able to handle multiple logic at the same time. By writing the state machines properly the two state machienes do not interfere with each other and allow to split up state machines into multiple ones which can help create complex logic more simple and stable. | The above example loads and runs two state machines. The first one is running specific state machine. The second state machine provides two separate state machines able to handle multiple logic at the same time. By writing the state machines properly the two state machienes do not interfere with each other and allow to split up state machines into multiple ones which can help create complex logic more simple and stable. | ||
- | _Action | + | // |
This example shows how to use a factory to add a condition checking for a trigger and an action manipulating a trigger. | This example shows how to use a factory to add a condition checking for a trigger and an action manipulating a trigger. | ||
Line 301: | Line 292: | ||
< | < | ||
</ | </ | ||
- | </ | ||
- | |||
- | ====== Live Examples ====== | ||
- | |||
- | * [[https:// | ||
- | * [[https:// | ||
- | * [[https:// | ||
- | |||
- | ====== Element Class Properties ====== | ||
- | |||
- | Element class properties have the prefix **stateMachine.** or **stateMachine(id).** if id is not empty. | ||
- | |||
- | ===== path ===== | ||
- | Path to state machine XML (*.desm) to load. | ||
- | * Full name: " | ||
- | * Type: Path (*.desm) | ||
- | * Default Value "" | ||
- | * Example (*.deeclass) <code xml>< | ||
- | |||
- | ====== Required Behaviors ====== | ||
- | |||
- | This behavior does not require other behaviors. | ||
- | |||
- | ====== Optional Behaviors ====== | ||
- | |||
- | This behavior does not support optional behaviors. | ||
- | |||
- | ====== Persistency ====== | ||
- | |||
- | This behavior does support element class to be persistable (setPersistable). Saves state machine content (# | ||
- | |||
- | ====== API Documentation ====== | ||
- | |||
- | # | ||
- | |||
- | Since DragonScript Module Version **1.3** | ||
- | |||
- | ====== Use Cases ====== | ||
- | |||
- | * Create element logic without writing state machine using scripts. | ||
- | * Reuse element logic across different elements. | ||
- | * Split element logic into smaller logic units using multiple state machines (potentially reused). | ||
- | |||
- | ====== Element Class Example ====== | ||
- | |||
- | Element class using a state machine loaded from " | ||
- | |||
- | < | ||
- | class MyElementClass extends BehaviorElementClass | ||
- | | ||
- | var ECBehaviorStateMachine smbehavior = ECBehaviorStateMachine.new(this) | ||
- | smbehavior.getPath().setValue("/ | ||
- | | ||
- | // here you can add now behaviors assigining actions and conditions for | ||
- | // the state machine to use | ||
- | ... | ||
- | | ||
- | // add listeners to behaviors to send events to the state machine | ||
- | var ECBehaviorTwoStateAnimated animated = ... | ||
- | animated.addActionConditionFactory(MyEventListener.Factory.new(smbehavior)) | ||
- | end | ||
- | |||
- | // two state listeners used to send events | ||
- | class MyEventListener extends ECBehaviorTwoStateAnimated.DefaultListener | ||
- | class Factory implements ECBehaviorTwoStateAnimated.ActionConditionFactory | ||
- | | ||
- | |||
- | | ||
- | this.stateMachine = stateMachine | ||
- | end | ||
- | |||
- | | ||
- | return MyEventListener.new(stateMachine.instance(instance.getElement())) | ||
- | end | ||
- | end | ||
- | |||
- | | ||
- | |||
- | | ||
- | this.stateMachine = stateMachine | ||
- | end | ||
- | |||
- | | ||
- | stateMachine.runEvent(" | ||
- | end | ||
- | |||
- | | ||
- | stateMachine.runEvent(" | ||
- | end | ||
- | end | ||
- | end | ||
</ | </ | ||