前回:DOTween完全に理解するその5 Sequence編
今回解説するもの
今回はDOTweenのイベントについて解説していきたいと思います。
イベントはTweenに特定のタイミングで処理を挟むのに有効ですが、
設定や状況によっては想定と違う動作を起こすので注意が必要です。
開発環境
Unity:2019.4.0f1
DOTween:v1.2.335
イベント登録API
| API | 概要 |
|---|---|
| OnStart | 動作開始時に1度だけ呼ばれる |
| OnPlay | 動作開始時に毎回呼ばれる |
| OnUpdate | 動作中毎フレーム呼ばれる |
| OnPause | 動作停止時に毎回呼ばれる |
| OnComplete | 正方向の動作完了時に呼ばれる |
| OnStepComplete | 動作完了時に呼ばれる 各ループの完了時にも呼ばれる |
| OnRewind | 初期位置に戻った時に呼ばれる(PlayBackwardsなどで逆再生した場合も含む) |
| OnWaypointChange | DOPathで各Pathに到達した時に呼ばれる Pathのインデックスが引数で |
| OnKill | Tweenが破棄される時に呼ばれる(Tweenがリサイクルされる場合も呼ばれる) |
各イベントの特徴
OnStart
動作開始時に1度だけ呼ばれます。
それ以降はRestart()やRewind()を使用しても呼ばれることはありません。
また、TweenにDelayがかかっていた場合Delayが終わった後に呼ばれます。
(個人的にはこれが少し使いづらいかなと思う時もあります...)
Play()などを行わずにComplete()で終端まで実行した後PlayBackwards()などで逆再生した場合にも呼ばれます。
Sequenceの場合は先頭にAppendInterval()やPrependInterval()をした場合でも
動作開始時にOnStartが呼ばれます(OnPlayも同様)
OnPlay
停止状態から動作開始した時に毎回呼ばれます。
OnStartと同様にDelayの影響を受けます。
PlayForward()、PlayBackwords()、SmoothRewind()など
停止中に動作を開始するAPIが呼ばれた場合にイベントが呼ばれますが、
動作中にこれらのAPIで再生方向が変わったとしてもOnPlayは呼ばれません。
また、すでにOnPlayが呼ばれた状態でGoto(andPlay:true)を呼んだ場合もOnPlayは呼ばれません。
OnUpdate
動作中に呼ばれます。
ただあまり使うシチュエーションは無い印象です。
OnStartと同様に通常のTweenの場合はDelayの影響を受け、
Sequenceの場合はDelay(Interval)の影響を受けません。
OnPause
動作停止時に呼ばれます。
AutoKill=falseの場合は動作完了時にも呼ばれる為、
OnCompleteやOnStepCompleteとタイミングがシビアになります(後述)
AutoKill=trueの場合は動作完了時にOnKillが呼ばれOnPauseは呼ばれません。
OnComplete
動作完了時に呼ばれます。
ただ、通常再生の場合にのみ呼ばれPlayBackwards()などで逆再生の場合は
動作完了時であっても呼ばれません。
また、Complete()実行時にも呼ばれます。
OnStepComplete
動作完了時に呼ばれ、通常再生、逆再生に関わらず呼ばれます。
SetLoop()で設定したループの一動作が終わる度に呼ばれます。
Complete()、Rewind()、Goto()などで動作が終了した場合は呼ばれません。
OnRewind
Tweenが初期位置に戻った時に呼ばれます。
初期位置というのは経過時間が0秒の位置のことを指します。
PlayBackwards()やSmoothRewind()でアニメーションが終わった場合に呼ばれますが
LoopType.Restartでアニメーションがループされる場合は呼ばれません。
また、Rewind()実行時にも呼ばれます。
OnWaypointChange
DOPath限定のイベントです。
DOPath生成時に設定したPathに到達した時に呼ばれます。
引数にPathのインデックスが渡されてきます。
SetOption()でClosePath=trueだった場合などでIndexが変わります(後述)
OnKill
Tweenが破棄される時に呼ばれます。
破棄される時と言ってもTweenがRecycable=trueでも呼ばれます。
再生されていない状態でComplete()を実行した場合にも呼ばれます。
AutoKill=falseの場合は動作完了時にOnPauseが呼ばれOnKillは呼ばれません。
注意すべきイベントの挙動
動作完了時に呼ばれるイベント群とその優先順位
通常の再生の場合はOnStepCoplete > OnComplete > OnKill/OnPauseの順で呼ばれます

逆再生の場合はOnRewind > OnStepComplete > OnPauseの順で呼ばれます。

よくあるパターンとしてスライドインしてくるUIを作った場合は
OnCompleteに通常再生の終了処理を書いて、OnRewindに逆再生の終了処理を書くのが良いかなと思います。
Sequence内のTweenのイベント
以下はイベントを設定したTweenに直接SetLoop()でLoopType.Yoyoを設定しています。
各Loop終了時にOnStepCompleteが呼ばれていることが確認できます。

以下は同じイベントを設定したTweenをSequenceにAppendし、SequenceにSetLoop()を行なっています。

各Loop終了時にOnCompleteやOnRewindが発生するようになっています。
このようにSequence内にあるTweenのイベントは個別に状況に合わせたイベントが呼ばれます。
OnWaypointChangeのindex
OnWaypointChangeの引数として来るindexはDOPathの設定によって変わります。
一般的な場合(ClosePath=false、ループなし)
| index | 場所 |
|---|---|
| 0 | 初期位置 |
| 1 | Path[0] |
| 2 | Path[1](終了位置) |
ClosePath=trueの場合
ClosePath=trueの場合、終了位置が初期位置になりますがその場合は
Indexが0ではなくPath総数+1になります。
| index | 場所 |
|---|---|
| 0 | 初期位置 |
| 1 | Path[0] |
| 2 | Path[1] |
| 3 | 終了位置(初期位置) |
![]() |
ClosePath=trueでLoopする場合
ClosePath=trueでSetLoopを設定した場合は複雑になります
LoopType.Restartの場合はLoopなしの時と同じように
Restartした初期位置はIndex=0で終了位置はPath数+1になります。

LoopType.Yoyoの場合は
逆再生する直前のIndexはPath数+1となり、逆再生中は各PathのOnWayPointChangeは2回ずつ呼ばれる
という挙動になります。

この2回ずつ呼ばれるという挙動が結構曲者で、ドキュメントにも特に何も書いてないので
もしかしてバグなんじゃ...なんて思います。
同じIndexのコールバックは無視するような対応を行い、OnStepComplete時に無視フラグをリセットするような実装が必要になるかと思います。
まとめ
イベントはエフェクトを表示したり、入力の受付状態の切り替えなど
DOTweenとは別の仕組みと連携するために使用されることが多いと思います。
特にOnStepCompleteやOnPause、OnRewindなどは使うシチュエーションはよく使うことになるので
DOTweenを応用して使う場合は身につけておくべき要素ですね。
余談ですがこの記事を書いていた7/29に
DOTweenの新バージョン(1.2.420)がAssetStoreで公開されたようです。
async/await対応
Sequence向けのSetDelayの拡張
ゲームでよく使いそうなカウントを使用するDOCounter
1文字ずつにアニメーションを行えるDOTweenTMPAnimator
などの良さそうな変更がかかっているようです。
特にDOTweenTMPAnimatorがかなり強力そうなのでこれを機にPRO版を購入しようと思います。
Sent #DOTween + Pro update to the Asset Store, with lots of new stuff (and some bugfixes) like TextMesh Pro per-character animation/transforms (Pro only): https://t.co/sI2qJVllFC
— 💬Daniele Giardini (@demigiant) July 24, 2020
(no DOTween Timeline yet but that's the next step for real :P) pic.twitter.com/fyDdq5MSGo

