MRが楽しい

MRやVRについて学習したことを書き残す

UniTaskを使ってゲームオブジェクトが破棄されたときのタスクのキャンセル処理を実装する

本日は UniTask の小ネタ枠です。
UniTaskを使ってゲームオブジェクトが破棄されたときのタスクのキャンセル処理を実装する方法を記事にします。

ゲームオブジェクトが破棄されたときのキャンセルトーク

UniTask の GetCancellationTokenOnDestroy 関数を使うとオブジェクトが破棄されたときにキャンセルされるトークンを取得できます。
合わせて SuppressCancellationThrow オペレータを使ってタスクがキャンセルしたか否かのフラグを取得することで簡単にゲームオブジェクトが破棄されたときの処理を記述できます。

実装例

以下にサンプルスクリプトを作成しました。シーンが再生されると10秒待機するタスクを実行します。
何もしなければタスクは10秒後に完了判定となり、それまでにゲームオブジェクトが破棄されればキャンセル判定となります。
・CancellationTokenOnDestroyTest.cs

using System;
using Cysharp.Threading.Tasks;
using UniRx;
using UnityEngine;

public class CancellationTokenOnDestroyTest : MonoBehaviour
{
    async void Start()
    {
        // このスクリプトがアタッチされているGameObjectが破棄されたらキャンセルされるCancellationTokenを取得する
        var cancellationTokenOnDestroy = this.GetCancellationTokenOnDestroy();

        // 10秒後に完了するタスクを作成する
        // 10秒以内にGameObjectが破棄されたらキャンセルされる
        // SuppressCancellationThrowでタスクがキャンセルされたか否か(IsCanceled)を取得できる型に変換する
        var taskResult = await Observable.Timer(TimeSpan.FromSeconds(10.0f))
            .ToUniTask(true, cancellationTokenOnDestroy)
            .SuppressCancellationThrow();
        
        if (taskResult.IsCanceled)
        {
            // タスクがキャンセルされたときの処理
            Debug.Log("キャンセルされました");
        }
        else
        {
            // タスクが正常に完了したときの処理
            Debug.Log("完了しました");
        }
    }
}

動作確認

シーンを再生して動作を確認します。
10秒間何もしなければタスクは正常に完了し、完了のデバッグログが出力されました。

一方シーンを再生して10秒以内にオブジェクトを削除するとタスクはキャンセルされ、キャンセルのデバッグログが出力されました。