You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
how to keep composite node retick running child? #12
Let's say I have a CharacterController state machine with the following states:
Idle
Moving Towards Enemy
Attack Enemy
And a Behavior Tree composed of the following nodes:
Sequence:
Check: If Enemy in field of view, then SUCCESS, else FAILURE
Task: Transition CharacterController to state Moving Towards Enemy, then SUCCESS
Check: If Enemy in attack range, then SUCCESS, else RUNNING
Task: Transition CharacterController to state Attack Enemy, then RUNNING
Now, an enemy comes into the field of view, so the first check succeeds, which means the task is executed, which change the state machine's state. The enemy is not yet in attack range, so the second check is still RUNNING, therefore the sequence node is RUNNING as well (the last task is not executed this tick).
Then, you run the state machine's update (its tick) which moves the character towards the enemy.
Next tick, the enemy is still into the field of view, so the first check succeeds, the first task transitions the state machine (which is a no-op since it is already in that state), then the second check is executed. The enemy is now in attack range, so the check succeeds and we move on to the second task which transitions the CharacterController to the Attack Enemy state and returns RUNNING, the sequence node is therefore still RUNNING.
Then, you run the state machine's update which kills the enemy.
Next tick, there is no enemy in the field of view, so the first check returns FAILURE, and therefore the sequence node returns FAILURE.
TL;DR: To maintain state between ticks, I'd use a state machine given to the behavior tree via its "world" data structure.
Activity
linkdd commentedon Mar 13, 2024
Let's say I have a
CharacterControllerstate machine with the following states:And a Behavior Tree composed of the following nodes:
SUCCESS, elseFAILURECharacterControllerto stateMoving Towards Enemy, thenSUCCESSSUCCESS, elseRUNNINGCharacterControllerto stateAttack Enemy, thenRUNNINGNow, an enemy comes into the field of view, so the first check succeeds, which means the task is executed, which change the state machine's state. The enemy is not yet in attack range, so the second check is still
RUNNING, therefore the sequence node isRUNNINGas well (the last task is not executed this tick).Then, you run the state machine's
update(its tick) which moves the character towards the enemy.Next tick, the enemy is still into the field of view, so the first check succeeds, the first task transitions the state machine (which is a no-op since it is already in that state), then the second check is executed. The enemy is now in attack range, so the check succeeds and we move on to the second task which transitions the
CharacterControllerto theAttack Enemystate and returnsRUNNING, the sequence node is therefore stillRUNNING.Then, you run the state machine's
updatewhich kills the enemy.Next tick, there is no enemy in the field of view, so the first check returns
FAILURE, and therefore the sequence node returnsFAILURE.TL;DR: To maintain state between ticks, I'd use a state machine given to the behavior tree via its "world" data structure.
I hope it answers your question 🙂
linkdd commentedon Mar 13, 2024
Also, moving this to a discussion rather than an issue.