Run a task async?

xjjon

New member
Is there a good way to have async tasks running within a sequence?

I want to be able to stagger tasks that may still be running after the sequence is complete.

For example - imagine a behavior where the entity casts a spell 3x. The spell task takes 2s to complete, but we want to introduce a 0.2s stagger between each cast.

[Sequence]
- CastSpell (2 second duration)
Wait 0.2s
- CastSpell (2 second duration)
Wait 0.2s
- CastSpell (2 second duration)
Wait 0.2s

The total duration of the sequence would be 0.6s (if the CastSpell task could be done async).

I have been able to create this with a lot of nested parallel / sequence sub tasks, but ideally it would be nice to be able to do it in 1 sequence.
 
I may be misunderstanding the problem but I think you should be able to create a new task which calls your cast spell function and then returns running for as long as your cast spell is active.
 
Yeah that is what I am doing now - but it is very verbose in the behavior tree. See example below:

* Radial Damage Task is the spell (which keeps track of duration and returns Running as long as it's active)

This will basically do the following

Starting from the red arrow:

[Parallel]
1) Start casting first spell
2) Start sequence for 2nd/3rd cast of spell - which has 0.1s wait before 2nd/3rd casting spell (this one casts twice in parallel)
3) Start sequence for 4th cast of spell - which has 0.2s wait before casting 4th spell
4) Start sequence for 5th cast of spell - which has 0.3s wait before casting 5th spell

So the timeline basically looks like

0s | cast 1st spell |
0.1s | cast 2nd, 3rd spell |
0.2s | cast 4th spell |
0.3s | cast 5th spell |

Which works - however it is not really easy to read and understand from the graph.

If I could somehow mark the "radial damage task" as async/nonblocking (i.e. moves onto the next task while it's still running, then it could be simplified as a sequence)


1605894191426.png

Example of how it could be simplified if it was non-blocking
And an additional example of how it could be used with a repeater


1605894657090.png

So to recap - was basically wondering what's the best way to create a task that would be non-blocking but still depend on the lifecycle of the behavior tree. (i.e. if the component / enemy dies, the task should also die with it). Of course we could fire off the spell to an external component / manager / etc but then that will require lifecycle checks on the behavior tree to see if it was interrupted, killed, etc, which makes it more complicated.

Thanks
 
If I could somehow mark the "radial damage task" as async/nonblocking (i.e. moves onto the next task while it's still running, then it could be simplified as a sequence)
The way to do this with the behavior tree design is to use a parallel task. There isn't a way to just have a single task return an async status without blocking the other tasks. If you go the parallel route you'll probably need to add some logic to your task to determine if the other tasks have completed, which you can do by referencing the task directly (similar to this post: https://opsive.com/forum/index.php?...dify-variables-values-in-specific-nodes.4284/)
 
Top