LoginSignup
35
16

More than 3 years have passed since last update.

DOTween完全に理解するその5 Sequence編

Last updated at Posted at 2020-07-25

前回:DOTween完全に理解するその4 DOPath編

今回解説するアニメーション

今回はDOTween最重要と言っても過言ではないSequenceについて解説します。
Tweenを繋げて1つのアニメーションとして連続実行させることができ、
複雑なアニメーションを作ることができます。

開発環境
Unity:2019.4.0f1
DOTween:v1.2.335

Append

sequence11.gif

var sequence = DOTween.Sequence(); //Sequence生成
    //Tweenをつなげる
    sequence.Append(transform.DOMoveX(7, 1))  
            .Append(transform.DOMoveX(-7, 1)) 
            .Append(transform.DOMoveX(0, 1)); 

Sequenceの末尾にTweenを追加します。
前のTweenが終わり次第次のアニメーションが実行されます。
内部的にはTweenの終了を待っているわけではなく、
前のTweenが終わる時間までDelayしている感じです

AppendInterval / AppendCollback

sequence12.gif

//TweenをつなげつつAppendIntervalとAppendCallbackを使う
sequence.Append(transform.DOMoveX(7, 1))
        .AppendInterval(0.25f)
        .AppendCallback(() =>
        {
            targetRenderer.material.color = Color.yellow;
        })
        .Append(transform.DOMoveX(-7, 1))
        .AppendInterval(0.25f)
        .AppendCallback(() =>
        {
            targetRenderer.material.color = Color.cyan;
        })
        .Append(transform.DOMoveX(0, 1));

Appendと同様に末尾に待機時間やコールバックを追加します。

Join

sequence21.gif


//Joinで並列動作するTweenを追加
sequence.Append(transform.DOMoveX(7, 1))
        .Join(transform.DORotate(new Vector3(0, 180), 1.5f, RotateMode.WorldAxisAdd)) //0 ~ 1.5
        .AppendInterval(0.25f) //1.5 ~ 1.75
        .AppendCallback(() =>
        {
            targetRenderer.material.color = Color.yellow;
        })
        .Append(transform.DOMoveX(-7, 1)) 
        .Join(transform.DORotate(new Vector3(0, 180), 1.5f, RotateMode.WorldAxisAdd)) //1.75 ~ 3.25
        .AppendInterval(0.25f) //3.75 ~ 4
        .AppendCallback(() =>
        {
            targetRenderer.material.color = Color.cyan;
        })
        .Append(transform.DOMoveX(0, 1))
        .Join(transform.DORotate(new Vector3(0, 180), 1.5f, RotateMode.WorldAxisAdd)); //4 ~ 5.5

直前のTweenと並行して動作するようにTween追加を行います。
Joinの後Appendした場合もっとも時間のかかったTweenの後に実行されます。

API アニメーション時間 開始時間〜終了時間
Append 5秒 0〜5秒
Join 10秒 0〜10秒
Append 5秒 10~15秒

Insert / InsertCallback

sequence31.gif

//Method2と同じ動きをInsertで行う
sequence.Append(transform.DOMoveX(7, 1.5f))  //0 ~ 1.5
        .AppendInterval(0.25f)                                 //1.5 ~ 1.75
        .Append(transform.DOMoveX(-7, 1.5f)) //1.75 ~ 3.25
        .AppendInterval(0.25f)                                 //3.25 ~ 3.5
        .Append(transform.DOMoveX(0, 1.5f)); //3.5 ~ 5

sequence.Insert(0, transform.DORotate(new Vector3(0, 0, 1800), 5.5f, RotateMode.WorldAxisAdd));

sequence.InsertCallback(1.75f, () =>
{
    targetRenderer.material.color = Color.yellow;
});
sequence.InsertCallback(3.5f, () =>
{
    targetRenderer.material.color = Color.cyan;
});

時間を指定して、Tweenerやコールバックを挿入します。
AppendやJoinとは異なり前後のTweenerなどに関係なく並列で動作します。

Prepend / PrependCallback / PrependInterval

sequence41.gif

var sequence = DOTween.Sequence();
sequence.Append(transform.DOMoveX(7, 1))
        .Append(transform.DOMoveX(-7, 1))
        .Append(transform.DOMoveX(0, 1));

//前に追加する
sequence.PrependInterval(0.5f);
sequence.PrependCallback(() => { targetRenderer.material.color = Color.red; });
sequence.Prepend(transform.DORotate(new Vector3(0, 0, 180), 1, RotateMode.WorldAxisAdd));

Sequenceの先頭にTweenerやコールバックを追加します。
先頭に追加されていくので、最後に追加したものから最初に実行されます。

Sequence同士をSequenceで繋ぐ

sequence51.gif

//SequenceにSequenceに追加する
var move = transform.DOMoveX(6, 0.5f)
                    .SetRelative(true)
                    .SetLoops(2, LoopType.Incremental);
var rotate1 = transform.DORotate(Vector3.forward * 90, 0.5f, RotateMode.WorldAxisAdd);
var sequenceA = DOTween.Sequence()
                       .Append(move)
                       .Join(rotate1);

var scale = transform.DOScale(1, 0.5f);
var rotate2 = transform.DORotate(Vector3.forward * 90, 0.5f, RotateMode.WorldAxisAdd)
                       .SetRelative(true);
var sequenceB = DOTween.Sequence()
                       .Append(scale)
                       .Insert(0.5f, rotate2)
                       .SetLoops(2, LoopType.Yoyo);

_tween = DOTween.Sequence()
                .Append(sequenceA)
                .Join(sequenceB);

_tween = DOTween.Sequence()
                .Append(_tween)
                .Append(transform.DORotate(Vector3.forward * 180, 1f, RotateMode.WorldAxisAdd));

SequenceもTweenerなので、Sequence同士をSequenceで繋ぐこともできます。
またSetLoops()をしたTweenerをSequenceに含めることもできますし
Sequence自体にSetLoops()をすることもできます。

Sequenceを使用する際の注意点

無限ループが使えない

例えば以下のようなSequence内のTweenerが無限ループする設定は無視されます。
Sequenceが無限ループする場合は問題ありません。

var move = transform.DOMoveX(1, 0.5f)
                    .SetRelative(true)
                    .SetLoops(-1, LoopType.Incremental);
var sequence = DOTween.Sequence()
                      .Append(move);

無効化される設定

SetAutoKill(true)やSetSpeedBased(true)などの設定は、
Sequence追加時にfalseに設定されてしまいます。

普通に考えればSeuqnceが終わっていない以上
PlayBackwordなどで実行済みのTweenを実行する必要が出てくるので
その際にKillされていたら困る為、設定が無効化されるのでしょう。

SpeedBaseもSequence自体は全て時間ベースで追加や挿入が行われる為
設定が無効化されるのだと思われます。

Sequenceに追加する前に設定を終わらせる

Tweenに対する設定はSequenceに追加する前に終わっている必要があります。
以下のようにSequence追加後のTweenへの設定は無視されます。
Sequence追加前に行った設定は正しく反映されます。(もちろん無効化されるもの以外)

var move = transform.DOMoveX(1, 0.5f)
                    .SetRelative(true);
var sequence = DOTween.Sequence()
                      .Append(move);
move.SetDelay(3f);
move.SetLoops(2, LoopType.Incremental);
move.From(0);

まとめ

Sequenceは作りが単純な分できることがかなり多い為、様々な場面で活躍します。
UnityはデフォルトではAnimator/Animationを使ってアニメーションを作ると思います。
ただ、Animatorの場合は固定化されたアニメーションを作るのには向いていますが
状況によって微妙に変化するアニメーションなど
コードから動きを細かく制御したい場合はSequenceが有効です。
Inspectorにアニメーション用のパラメータを出しておけば調整も簡単です。
あとこれは全てのTweenに該当しますがTimeScaleで個別に速度を変えられる点も強力だなぁと最近思いました。

最後に最近作ったどこで使うかわからないアニメーションを置いておきます。ご査収ください。

35
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
16