asyncなメソッド内でLerpを使う方法(でもDOTween使った方が楽かも) #Unity
asyncなメソッド内でLerpをつかってなめらかに位置を動かす方法について、意外と情報が見つからなくて苦戦したので、書き残しておきます。
カメラの位置(Offset)と画角(OrthographicSize)をなめらかに動かしたくて作ったスクリプトです。現在位置がoldOffset・oldOrtho、動かしたい位置がnewOffset、newOrtho、動かす時間がdurationです。このコードの外で、offset、orthographicSizeの値を、毎フレームLateUpdateでカメラに渡しています。
using Cysharp.Threading.Tasks;
// 中略 //
for (float t = 0f; t < duration; t += Time.deltaTime)
{
offset = Vector3.Lerp(oldOffset, newOffset, t / 0.5f);
orthographicSize = Mathf.Lerp(oldOrtho, newOrtho, t / duration);
await UniTask.Yield();
}
Time.deltaTimeを使っているので、for内でawait UniTask.Yield()で1フレーム待つようにしないといけないことに気づくまで時間がかかりました。初心者はこういうところで躓くのです(涙)。
ちなみに、書いてから気づいたのですが、UniTaskを入れてawaitを使うならDOTweenをを使った方がスマートかもしれません。一応、書いてみたら動いたので本番ではこちらにしました。
using Cysharp.Threading.Tasks;
using DG.Tweening;
// 中略 //
await UniTask.WhenAll(
DOTween.To(
() => offset,
(x) => offset = x,
newOffset,
duration)
.SetEase(Ease.InOutSine).AwaitForComplete(),
DOVirtual.Float(oldOrtho, newOrtho, duration,
value => orthographicSize = value).AwaitForComplete()
);
UniTaskでDoTweenをawaitするには、以下の記事にあるようにBuildSettings → PlayerSettings → PlayerのScripting Define Symbolsに UNITASK_DOTWEEN_SUPPORT と設定する必要があります。
どちらがいいのかは、まだわからないので、いつか有識者に聞いてみたいと思います。