Using Async/Await

Someone suggested I post this here as it was discussed in the discord here: https://discord.com/channels/437989205315158016/438021403220901889/1079543928044408933. When using async/await, Flax follows the standard c# threading rules.

If you want to cancel an async method you will need to use a cancellation token to cancel it when you need to (for example: in OnDestroy() when exiting game or play mode). Common errors/issues arise from people not handling these correctly (for example: something continuously spawning objects even when play mode is exited).

In the game I put together, https://tryibion.itch.io/kitty-dinks-remake, I have an example of using async code to change the idle animations of the cat in the selection menu on a set interval. This includes the cancellation and clean up code for the async task in OnDestroy(). The code below is only a snippet of the code used, so not all of the variables involved are declared

private Task _asyncChangeAnimTask;
private CancellationTokenSource cToken = new CancellationTokenSource();
private bool _playCatAnims = true;

public override void OnStart()
{
    _asyncChangeAnimTask = Task.Run(ChangeAnimation, cToken.Token);
}

private async Task ChangeAnimation()
{
    while (_playCatAnims)
    {
         try
         {
            await Task.Delay(Mathf.FloorToInt(AnimationChangeTime * 1000), cToken.Token);
         }
         catch (Exception e)
         {
            _playCatAnims = false;
            return;
         }
                
         Animation nextAnim = IdleAnimations[_randomStream.RandRange(0, IdleAnimations.Count - 1)];
         _animatedModel.PlaySlotAnimation("Default", nextAnim, 1, 0.5f, 0.5f);

         if (cToken.IsCancellationRequested)
         {
             _playCatAnims = false;
             return;
         }
    }
}

public override void OnDestroy()
{
    if (_asyncChangeAnimTask != null)
      {
          cToken.Cancel();
          _asyncChangeAnimTask.Wait(100);
      }
}

As you can see from the code, you have to pass the cancellation token into the async method AND handle what you want the method to do when the cancelation is called.

3 Likes