Raspberlyのブログ

Raspberlyのブログ

Unityネタをメインとした技術系ブログです。にゃんこ大戦争や日常なども。そろそろブログタイトル決めたい

【Unity】DOTweenでUIアニメーションが連続で呼ばれた時に少しずつズレる問題の解決方法【DOTween】

この記事はUnity Advent Calendar 2023 その2 24日目の記事です。

qiita.com

 

実行環境

Unity 2022.3.14f1

DOTween ver1.0.375

 

 

やること

DOTweenを使って連続でUIアニメーションを再生した時に、
少しずつズレる問題の解決方法についてまとめます。

 

 

 

解決方法

忙しい人向けに先に書いておきます。

 

連続でアニメーションを再生する時は、以下の方法でキャンセル処理をかけば解決します

  • .DOComplete()か.DOKill(true)でキャンセル
  • Sequenceを使っている時は.Complete()か.Kill(true)でキャンセル

 

つまり、実行中のアニメーションを最後まで再生しきってから次のアニメーションを実行すればいいわけです。
キャンセルしない、またはキャンセルに引数を渡さない.DOKill()を使うとこの問題がおきます。

 

 

 

 

 

 

 

 

 

 

以下、暇な人向け

少しずつズレる原因

この現象は、以下のアニメーション*1を連続で再生する時、キャンセル処理が正しくないと発生します

  • .SetRelative()をした相対的なアニメーション
  • DOShake系、DOJump系、DOPunch系

キャンセル処理が正しくないとは、
キャンセルに.DOKill()を使っている、またはキャンセルをしていない状態を指します。

 

 

ズレる例

実際にズレる例を出します。
こんな画面があり、InputFieldに文字が入力されていない状態でNextボタンが押されたら、
InputFieldを揺らすアニメーションを再生したい時。

 

揺らすアニメーションはDOTweenで実装。
やり方はいろいろありますが今回はDOPunchを使用します。

    [SerializeField] private RectTransform rectTransform;
    [SerializeField] private float duration;

    public void NegativeAnimation()
    {
        rectTransform.DOKill();
        rectTransform.DOPunchPosition(new Vector3(30, 0, 0), duration);
    }

 

NegativeAnimation()を再生するとこうなります

 

 

しかしキャンセル処理に.DOKill()を使っているので連打すると少しずつズレます



 

解決方法

先に書いた通り、キャンセル処理に.DOComplete()か.DOKill(true)を使用すれば解決します
DOKill()は引数を与えないと、最後までアニメーションを再生しきらずに終了するので注意。

public void NegativeAnimation()
    {
        //または rectTransform.DOComplete();
        rectTransform.DOKill(true);
        rectTransform.DOPunchPosition(new Vector3(30, 0, 0), duration);
    }

 

これで、最後までアニメーションを再生しきってから次のアニメーションを再生するのでズレません

 

Sequenceの場合

Sequenceでのキャンセルは、.Complete()か.Kill(true)です

    private Sequence sequence;
    
    public void NegativeAnimation()
    {
        //または sequence.Complete();
        sequence.Kill(true);
        sequence = DOTween.Sequence()
            .Append(rectTransform.DOLocalMoveX(-40, duration).SetRelative())
            .Append(rectTransform.DOLocalMoveX(40, duration).SetRelative());
    }

 

 

 

まとめ

連続でアニメーションを再生する時は、以下の方法でキャンセル処理をかけば解決

  • .DOComplete()か.DOKill(true)でキャンセル
  • Sequenceを使っている時は.Complete()か.Kill(true)でキャンセル

 

 

以上です。

 

 

 

おまけ CompleteとKillの違い

ここがわかりやすい

www.hanachiru-blog.com

 

 

過去のUnity アドベントカレンダー記事

raspberly.hateblo.jp

raspberly.hateblo.jp

 

過去のDOTween関係の記事

raspberly.hateblo.jp

 

raspberly.hateblo.jp

 

*1:他にもあるかも