初めに
await tweener.ToUniTask(cancellationToken:cancellationToken);
のようなコードを書いたらcancellationTokenのキャンセル時にOperationCanceledExceptionが発生しませんでした。どうやら引数によって発生の有無が変わるようなので挙動を調べました。
環境
- Unity2020.3.19f1
- UniTask 2.2.5
Tween.ToUniTaskのOperationCanceledException発生の有無
UniTask+DOTWeenでキャンセル処理をしたい場合、ToUniTaskメソッドでcancellationTokenを指定しますが、下のようなコードだと移動中にcancellationTokenがキャンセルされてもOperationCanceledExceptionが呼ばれず、以降の行が実行されて"Done"が出力されます。
public class Hoge : MonoBehaviour
{
private CancellationTokenSource _cancellationTokenSource;
async void Start()
{
_cancellationTokenSource = new CancellationTokenSource();
MoveTask(cancellationToken:_cancellationTokenSource.Token).Forget();
// 1秒後にキャンセル
await UniTask.Delay(1000, cancellationToken: _cancellationTokenSource.Token);
_cancellationTokenSource.Cancel();
}
private async UniTask MoveTask(CancellationToken cancellationToken)
{
try
{
Tweener tweener = transform.DOMove(new Vector3(2, 3, 4), 3);
await tweener.ToUniTask(cancellationToken:cancellationToken);
Debug.Log("Done");
}
catch (OperationCanceledException e)
{
Debug.Log(e);
throw;
}
}
}
DOTWeenのToUniTaskの引数にはキャンセル時の挙動を決めるtweenCancelBehaviour引数があり、その引数によってOperationCanceledException発生の有無が変わります。
tweenCancelBehaviour引数 | OperationCanceledExceptionの発生 |
---|---|
Kill(デフォルト) | なし |
Complete | なし |
CancelAwait | あり |
CompleteAndCancelAwait | あり |
CompleteWithSeqeunceCallback | なし |
KillAndCancelAwait | あり |
KillWithCompleteCallback | なし |
CompleteWithSeqeunceCallbackAndCancelAwait | あり |
KillWithCompleteCallbackAndCancelAwait | あり |
例えば下のコードのようにTweenCancelBehaviour.Completeを指定すると、cancellationTokenのキャンセル時にTweenが終了時の状態になり、OperationCanceledExceptionは発生しません。
public class Hoge : MonoBehaviour
{
private CancellationTokenSource _cancellationTokenSource;
async void Start()
{
_cancellationTokenSource = new CancellationTokenSource();
MoveTask(cancellationToken:_cancellationTokenSource.Token).Forget();
// 1秒後にキャンセル
await UniTask.Delay(1000, cancellationToken: _cancellationTokenSource.Token);
_cancellationTokenSource.Cancel();
}
private async UniTask MoveTask(CancellationToken cancellationToken)
{
try
{
Tweener tweener = transform.DOMove(new Vector3(2, 3, 4), 3);
await tweener.ToUniTask(tweenCancelBehaviour:TweenCancelBehaviour.Complete, cancellationToken:cancellationToken);
Debug.Log("Done");
}
catch (OperationCanceledException e)
{
Debug.Log(e);
throw;
}
}
}