DOTweenList: DOTween の複数の Tween をまとめて再生したり、待機したりできるようにする

はじめに

DOTween を使っていて、複数のアニメーションを同時に再生したり、完了を待機したりしたいという場面はよくありますよね。

単体のアニメーションなら作るのも楽ですが、アニメーションというものは複数の動きが複雑に連関しがちなもので、複雑になればなるほどコードも長く、ぐちゃぐちゃになっていきます。

例えば「A, B, C のアニメーションがすべて完了するまで待機」みたいなことをしたい場合、それらすべてに完了コールバックを設定して、すべてのコールバックが実行されたかどうかを毎フレーム確認する……みたいに書かねばならず*1、大変面倒です。

bool flagA;
bool flagB;
bool flagC;

void PlayTweens()
{
    transformA.DOMoveX(100f, 1f).OnComplete(() => flagA = true);
    transformB.DOMoveX(100f, 2f).OnComplete(() => flagB = true);
    transformC.DOMoveX(100f, 3f).OnComplete(() => flagC = true);
}

void Update()
{
    if (flagA && flagB && flagC)
    {
        // すべての Tween が完了したら実行される処理
    }
}

さらにその上、アニメーション中にボタンを押したらスキップできる、みたいな仕様が加わることも……。

そういったことがもっと簡単にできるように、複数の Tween を一つにまとめて一括で処理をしたり、待機したりできるようなクラスを作ってみました。

github.com

これを用いると、先の例はこんなふうに書けます。

async UniTask PlayTweensAsync()
{
    await new DOTweenList(
        transformA.DOMoveX(100f, 1f),
        transformB.DOMoveX(100f, 2f),
        transformC.DOMoveX(100f, 3f)
    );

    // すべての Tween が完了したら実行される処理
}

簡潔で、なかなか良くないですか?

説明

GitHub の README にも説明書きはありますが、ここではそれよりもう少し詳しめに説明をしていこうと思います。

注意

以下のアセットが別途必要です。

待機のところで UniTask を使用しています*2

インストール

上記 2 つのアセットをインポートしたあと、DOTweenList.cs を任意のディレクトリに配置してください。

UnityPackage を使用してインストールすることもできます。

使い方

準備

まず、DOTweenList に処理したい Tween を詰めます。以下の 3 つの方法があります:

(i) コンストラクター

var dotweenList = new DOTweenList(
    rectA.DOAnchorPosX(600f, 0.6f),
    rectB.DOAnchorPosX(600f, 0.8f),
    rectC.DOAnchorPosX(600f, 1f)
);

一番簡単。まとめたい Tween が最初から全部揃っている場合は、これを使うと良いでしょう。

(ii) Add()メソッド

var dotweenList = new DOTweenList();

dotweenList.Add(rectA.DOAnchorPosX(600f, 0.6f));
dotweenList.Add(rectB.DOAnchorPosX(600f, 0.8f));
dotweenList.Add(rectC.DOAnchorPosX(600f, 1f));

Add()を使えば、あとから別の Tween を追加することもできます。

(iii) AddTo()拡張メソッド

var dotweenList = new DOTweenList();

rectA.DOAnchorPosX(600f, 0.6f).AddTo(dotweenList);
rectB.DOAnchorPosX(600f, 0.8f).AddTo(dotweenList);
rectC.DOAnchorPosX(600f, 1f).AddTo(dotweenList);

Add()の拡張メソッド版です。お好みの方をお使いください。

処理を実行

DOTweenList には、以下の処理を実行できます。

// 再生
dotweenList.PlayForward();

// 逆再生
dotweenList.PlayBackwards();

// 最初に戻す
dotweenList.Rewind();

// 最後に進める
dotweenList.Complete();

// 強制終了
dotweenList.Kill();

メソッド名の末尾にByIdを加えることで、特定の ID の Tween のみに処理を実行できます。

dotweenList.PlayForwardById("id");

dotweenList.PlayBackwardsById("id");

dotweenList.RewindById("id");

dotweenList.CompleteById("id");

dotweenList.KillById("id");

また、PlayForward()PlayBackwards()には引数として bool 値を渡すことができ、true を設定するとアニメーションが途中であっても強制的に最初から(PlayBackwards()なら最後から)再生することができます。

// 最初から再生
dotweenList.PlayForward(true);

// こう書くのと同じ
dotweenList.Rewind();
dotweenList.PlayForward();

この他、以下のメソッドが用意されています。

// Tween がどれか一つでも再生中なら true を返す
dotweenList.IsPlaying();

// リストをクリアする
dotweenList.Clear();

// すべての Tween の再生開始から終了までにかかる時間を取得する
// 注意:Tween が再生中であっても、開始からの時間が返る
dotweenList.GetTotalTime();

// 特定の ID を持つすべての Tween の再生にかかる時間を取得する
// 注意:Tween が再生中であっても、開始からの時間が返る
dotweenList.GetTotalTimeById("id");

待機

awaitを付与することで、再生終了まで待機することができます。

// 再生を開始し、終了まで待機する
await dotweenList.PlayForward();

// すでに再生中の Tween を待つこともできる
await dotweenList;

// 昔ながらのコルーチンで待機しても OK
yield return dotweenList.PlayForward();

そして目玉機能! 拡張メソッドのSkippable()を用いれば、指定した条件で Tween をスキップすることができます。

// 再生終了まで待機する。何かキーを入力するとスキップする
await dotweenList.PlayForward().Skippable(() => Input.anyKeyDown);

DOTween Animation

DOTween Pro の機能である DOTween Animation を DOTweenList に詰める場合は、以下のように書きます。

var dotweenList = new DOTweenList(GetComponent<DOTweenAnimation>().GetTweens());

最後に

使っていておかしなところや改善点を見つけたら、Issues でご報告ください。Pull Request も大歓迎です!

*1:もしかしたらもっと良い書き方があるのかも知れませんが……もしあったらコメントで教えて下さい!

*2:UniTask は、Tween に限らず非同期処理をしたいときにめちゃくちゃ有用なので、await/async を使っているならぜひ導入すべきです。

The coloring of this site is Dracula PRO🧛🏻‍♂️
This website uses the FontAwesome icons licensed under CC BY 4.0.

2020 GIGA CREATION