Complex code made simple.
Async programming is a compiler feature of the C# language that rewrites what appears to be linear code into a state machine. This makes it much easier to write and understand complex gameplay logic.
In async programming, state is tracked using the natural
idioms of the language. We design the workflow based on
the natural primitives of the language - we insert
await prefix in places where we want to stop
execution, and our application resumes execution on the tick
where it left off.
ToKey see this in action, we override the
Actor, as illustrated by the following code:
A behavior that uses async styles might look like this:
This code snippet controls an actor's weapon shooting and
animations. You can see how the
await keyword is
useful here: in the first
while loop, you can see
a sort of state machine described--first, the Actor attempts
MoveTo() its target. When that is done, a
shooting animation is started
AnimateAsync(), followed by a shooting
ShootAt(). Once the shooting is done, a reload
animation is started. These states are looped until the target
is no longer visible or the actor runs out of ammo. All of
these states are traversed across a large number of frames,
instead of each method being called every tick.
During the execution of the
Update method, the thread's synchronization
context is replaced with a game-specific synchronization
context that will resume execution on the next Tick.
Any operation that is queued inside the
Update method will
not be dispatched by default into the default synchronization
context (which would typically have been just an idle handler
on the main loops).
Instead, the operations are only resumed and executed
when Unreal invokes the
ReceiveTick event. This
ensures that our code runs in the context that Unreal expects
it to run.
If we need to queue tasks from the
method to be executed in a different synchronization context,
we need to manually request that.