Need node break function
PlusLius opened this issue · comments
Need node break function
Expect Logic
- Cansee is used to find the target
- Cansee find the target then Seek track the target
- When a Walk is executed, a target is found and the Walk is break to execute the Cansee
Actual Situation
- There is no way to break the Walk and then execute the Cansee during the Walk execution
/ *
Root
|
Selector
/ \
Sequence Walk (If Cansee finds the target, the Walk is break)
/ \ |
Cansee Seek |
(need loop execution)
^ - - - - - -|
*/
Hey @PlusLius, sorry, for the delayed answer.
I am not quite sure how you implemented the Walk. Does it return RUNNING
? If so, try returning `SUCCESS``instead, to give the left part of the tree a change to be evaluated in the next run of the bTree. That way you don't need a "break" method.
Also a suggestion: I am not quite sure if Seek and Walk are different for you, but if they are principially the same (the one just has a target the other does not), you can also use the blackboard that is passed in to set a target to walk to, and then you need just one walk task, that walks to the target given in the blackboard (set by the cansee task) or just walks randomly. Just a thought/idea (without knowing what you actually want to achieve :-)).
Does this help to you?
Hello @Calamari Calamari is something that I didn't put very clearly, but what I'm trying to say is this situation
- The cansee node needs to run in a loop
- The CANSEE node needs to run at the same time as the WALK node
Why is this necessary?
- I want to realize that an object automatically tracks another object in the field of view. Suppose that the node tree has already executed in the walk node (the function of the walk node is to walk randomly), and another object has already appeared in the field of view of the object, at this time, the CANSEE node should be executed. But at this point the walk node is still executing the subsequent nodes,
- so it needs to break
Ok, I think I get what you want to achieve. I am not quite sure if the way I think you are thinking to do it is the right approach. I think your definition of "run in a loop" is different from mine. Here is how I would define it:
You have a game loop, that game loop is ran every – lets say – 15ms (exampe number, rounded down from 16.67ms to get 60FPS) and draws a frame. Also run every frame or every 10th frame is the AI logic, a.k.a. Behavior Trees of the agents in the game (bTree.step()
).
Does this adaquately match to "run at the same time"?
If that rings sensible to you, that would allow the following to you:
Currently, it sounds that your WALK node is also waiting and blocking the game loop and is animating itself, that's probably, why you need a break out of that behavior. But you can switch it up and unblock everything. Think about the following idea:
First you need:
If you want to track a target (some object in the field of view), you need a place to store it. The "blackboard" is a good place for that. If you have a (randomly chosen) walking target, the blackboard is also a good place to put that target (that coordinates) into as well.
Then you can achieve the desired behaviors and still stay in the typical game-loop way:
+----------+
| Sequence |
+----------\
--/ ---\
-/ ----\
--/ ---\
+------/---+ +--------------------------+
| Selector | | WalkToCurrentlySetTarget |
+-------\--+ +--------------------------+
/ \
/ \
/ \
/ \
/ \
+--------/-------+ +---------------------+
| IsEnemyInView? | | SetRandomWalkTarget |
+--------|-------+ +---------------------+
|
|
|
+-----|-----+
| SetTarget |
+-----------+
IsEnemyInView -> is a decorator that calls SetTarget if an enemy is in line of sight and returns FAILURE otherwise
SetRandomWalkTarget -> sets a randomly chosen coord to walk to if agent does not have any or reach the last one
WalkToCurrentlySetTarget -> Would start Animation of walking if not already in walking animation and if the step is run on every frame could potentially update the coords of the agent so he moves on the screen, or better start another tweening utility or something.
So to explain a bit more:
On every loop run where bTree.step()
is called, it runs sequence (since it is the root node), then this calls Selector, which calls IsEnemyInView?. If it finds one, that one calls SetTarget, Selector skips the SetRandomWalkTarget, since SetTarget returns SUCCESS, Then Sequence will call WalkToCurrentlySetTarget to start walking.
On the next frame, bTree.step()
is called again and it starts again on Sequence, then Selector, then IsEnemyInView, this time the enemy dissappeared, so SetTarget is not called, it returns FAILURE and the Selector will call the next node in line, that is SetRandomWalkTarget, which will then just choose a random point to walk to, that returns SUCCESS then Sequence is calling WalkToCurrentlySetTarget.
And on the next frame all this starts again…
With that pattern you could easily add other things in there, like attack if Enemy is in range, etc.
I hope this small tutorial style essay can help you jump start your progress. Would like to here if it helps, and if not, what is missing. Maybe I am missing the point still. :-)