Unityでは鉄板TweenのDOTweenをTweenMaxと比較して覚える


[FLASHer Advent Calendar 2016](http://qiita.com/advent-calendar/2016/flashers) 16日目の記事です。

TweenMax派かつ、DOTween派の[@katapad](https://twitter.com/katapad)です。
TweenMaxとDOTweenで、できることできないことを並べてみますね。
基本的に、仕事で使うやつと、使うと便利そうだな、ってやつをあげてます。

[明日(17日目)のアドベントカレンダー](http://qiita.com/sakusan393/items/83cbb861c485551cd6b0)担当者が[「すき家のカレー」を毎日昼夜と食べるひと](https://www.instagram.com/sakusan393/)なので、サンプルは全部 **すき家のカレーの皿** にしました。

![2016-12-13 22_04_37.gif](https://qiita-image-store.s3.amazonaws.com/0/2631/b75a902b-5a74-6b16-5700-765ec46700f4.gif "2016-12-13 22_04_37.gif")



![2016-12-13 22_01_29.gif](https://qiita-image-store.s3.amazonaws.com/0/2631/141f9a65-78b1-5ca0-7a64-abf16520914d.gif "2016-12-13 22_01_29.gif")
サンプルでよく見るイージングの比較もこの通り。


![2016-12-19 12_03_54.gif](https://qiita-image-store.s3.amazonaws.com/0/2631/f99bbf41-ad0d-6e9b-07ca-4086ddaa6d0e.gif "2016-12-19 12_03_54.gif")




## 本題の前にDOTween参考資料

DOTweenをググっていると必ず出てくるbao_baoさんのブログを見ると、ものすごく理解できます。
[今一番個人的にアツいUnityのTweenエンジン『DOTween』スニペット集 〜Transform編〜 - 渋谷ほととぎす通信](https://goo.gl/p43E0U)

それ以外は薄いドキュメントを読みましょう。
[DOTween - Documentation](http://dotween.demigiant.com/documentation.php)



## Tweenの基本


varsの数値は文字列にすると、relativeモードになります(いまいる位置から2.5動く)。

```TweenMax.js
var duration = 1.0;
TweenMax.to(target, duration, {x: 2.5})
TweenMax.to(target, duration, {x: "2.5"}) // Relative
TweenMax.from(target, duration, {x: 2.5})
TweenMax.fromTo(target, duration, {x: -2.5}, {x: 2.5})
```

DOTween
**残念ながらFromToはありません。**

```DOTween.cs
var x = 2.5f;
var duration = 1.0f;
transform.DOLocalMoveX(x, duration); //To
transform.DOLocalMoveX(x, duration).SetRelative() // Relative
transform.DOLocalMoveX(x, duration).From() // From

//delayとeasing
transform.DOLocalMoveX(x, duration).SetDelay(1f).SetEase(Ease.OutExpo);
```

その他の基本的なことはドキュメントを見ましょう。



### DOTweenにはパラメータ使い回し用に`SetAs`がある。

「メソッドチェーンのパラメータ使い回しめんどくさい問題」を解決するやつ、ありました。

```TweenParams.cs
// 使い回しパラメータ
TweenParams tParms = new TweenParams().SetLoops(-1).SetEase(Ease.OutElastic);
// SetAsでバコッとハメれます
transformA.DOMoveX(15, 1).SetAs(tParms);
transformB.DOMoveY(10, 1).SetAs(tParms);
```

## Back, Elasticの裏パラメータ

以下の2つのイージングは、裏パラメータが用意されていて、動きの大きさなどを調整できます。

* Back
* Elastic

↓ここで試せます。
http://greensock.com/ease-visualizer

```TweenMax.js
// Back は1つ
TweenLite.to(graph, 2.5, { ease: Back.easeOut.config(1.7), y: -500 });

// Elasticは2つ
TweenLite.to(graph, 2.5, { ease: Elastic.easeOut.config(1, 0.3), y: -500 });
```

**残念ながらDOTweenには裏パラメータはありません！**

が、似たようなものが用意されています。

* Punch
* Shake
* Jump

[今一番個人的にアツいUnityのTweenエンジン『DOTween』スニペット集 〜Transform編〜 - 渋谷ほととぎす通信](http://www.shibuya24.info/entry/2015/08/26/090000)

実はshakeはTweenMaxにもあったりします。


## カスタムイージング

TweenMaxはこちらにいろいろ書いてます。
[GreenSock | CustomEase](https://greensock.com/customease)

CSSの cubic-bezier()で指定したり、TweenMaxのサイトのカスタムイージングジェネレーターで思い通りに生成できます。

![うんこイージング](https://qiita-image-store.s3.amazonaws.com/0/2631/e36c13eb-1470-c06d-a178-a539ba870d4e.png "貼り付けた画像_2016_12_16_20_32.png")

うんこ風カスタムイージングも作れる

```TweenMax.js
TweenLite.to(graph, 2.5, { ease: CustomEase.create("custom", "M0,0,C0.126,0.382,0.002,0.862,0.16,1.01,0.352,1.19,0.818,1,1,1"), y: -500 });
```

DOTweenに関しては渋谷ほととぎす通信さんが最高にありがたく書いてくれているので、そちらを見ましょう。

[Unity DOTweenのカスタムイージング - 渋谷ほととぎす通信](http://www.shibuya24.info/entry/2016/10/21/220000)


## 任意のプロパティをTweenさせる

TweenMaxはわりとなんでもTweenできますが、DOTweenはtransformにくっついてたりするので、自由自在にしたいときはと、ちょっとちがう書き方をします。

```DOTween.cs
public float tweenValue;
void Start() {
  //tweenValueを100fまで3fでtweenさせる
  DOTween.To(() => tweenValue, x => tweenValue = x, 100f, 3f);
}
```

//参考
[今一番個人的にアツいUnityのTweenエンジン『DOTween』スニペット集 〜カスタムプロパティ編〜 - 渋谷ほととぎす通信](http://www.shibuya24.info/entry/2015/09/14/090000)

というのがよくみるヤツなのですが、実は簡易的にできるやつが用意されています。

### Virtual methodsが使いやすい

floatをちょいと動かしたいときは、普通に.To()するよりかんたん。

```DOTween.cs
//DOVirtual.Float(from, to, duration, onUpdate)
DOVirtual.Float(0f, 100f, 3f, value =>
{
  Debug.Log("value: " + value);
});
```


## ベジェ

bezierに配列をぶっこむと、いいかんじにベジェしてくれます。ベジェのオプションもいくつかあります。
[GreenSock | Docs - HTML5 GSAP Plugins BezierPlugin](https://greensock.com/docs/#/HTML5/GSAP/Plugins/BezierPlugin/)

```TweenMax.js
TweenMax.to(document.getElementById("myDiv"), 5, {bezier:[{left:100, top:250}, {left:300, top:0}, {left:500, top:400}], ease:Power1.easeInOut});
```

DOTweenには`DOPath`, `DOLocalPath` があります。position系にしか適用できません。scaleやら任意のプロパティなどはカスタムイージングで対応しましょう。

```DOTween.cs
target.transform.DOLocalPath(new Vector3[] {
 new Vector3 (0.2f, 1f), Vector3.zero, new Vector3 (-3f, 2f)
}, 3f).OnWaypointChange(OnWayPointChange); // OnWayPointChangeでポイントを通過するたびに通知できる
```

![2016-12-16 19_48_30.gif](https://qiita-image-store.s3.amazonaws.com/0/2631/abefad1f-15ee-683e-4a5f-2c8a216cda70.gif "2016-12-16 19_48_30.gif")
クリスマスツリーにも見えるが、まきまきウンコパスにそってすき家のカレーの皿が動いている。


## ループ

TweenMax, DOTweenともに、-1を入れると無限。

```TweenMax.js
// repeatDelay: リピートするときのdelay, yoyo: 行って返ってくるタイプ
TweenMax.to(mc, 1, {x:1, repeat:-1, repeatDelay: 1, yoyo: true});

```

```DOTween.cs
transform.DOMoveX(x, 1f).SetLoops(-1, LoopType.Yoyo);
//LoopTypeはYoyoだけでなく、終わった位置から開始するLoopType.Incrementalもある
```

![2016-12-16 20_53_09loop.gif](https://qiita-image-store.s3.amazonaws.com/0/2631/5415807c-58aa-9ffc-e064-e13da55bc80b.gif "2016-12-16 20_53_09loop.gif")
LoopTypeの比較。

渋谷ほととぎす通信ではループの罠が解説されています。
[今一番個人的にアツいUnityのTweenエンジン『DOTween』の罠〜ループ編〜 - 渋谷ほととぎす通信](http://www.shibuya24.info/entry/2016/10/08/141314)


## stagger

TweenMaxの神機能。配列を入れると、いい感じにバラけさせながらそれぞれをTweenさせてくれます。

```TweenMax.js
//0.08秒間隔で、0.7秒でxを移動するtweenを実行
TweenMax.staggerTo(".unko" , 0.7 , {x:1} , 0.08)
```

**残念ながらDOTweenにはない…。**forで回しましょう…。


## DelayedCall

TweenMaxはパラメータもつっこめます。

```TweenMax.js
TweenLite.delayedCall( delay:Number, callback:Function, params:Array , scope:*, useFrames:Boolean ) : TweenLite
```

DOTweenはラムダ式でなんとかするタイプ。パラメータはラムダ式でなんとかしましょう。

``` DOTween.cs
DOVirtual.DelayedCall (1f, ()=>Hoge());
```

## Kill、スキップなどコントロール系

DOTweenはKillの引数isCompleteをtrueにすると実行後の値までスキップできる。

```DOTween.cs
DOTween.Kill(transform, true);
DOTween.KillAll()
DOTWeen.PauseAll()
```


めずらしいところで

Rewind, Restart, PlayBackwordsなどがあります。(使ったことない)


## DOTweenならではのもの

* コルーチン
	* http://dotween.demigiant.com/documentation.php#coroutines
	* Tweenがcompleteしたらコルーチンが進むやつとかがある。
	* OnCompleteやOnStartのコルーチン版みたいな。


## コールバック、イベント

TweenMax

* onComplete
* onReverse
* onStart
* onUpdate
* onOverwrite
	* オーバーライト(上書き実行)されたとき


DOTween
DOTweenには特殊なものがいくつかあります。

* OnComplete
* OnKill
* OnPlay
* OnPause
* OnRewind
	* Rewindしたとき
* OnStart
* OnStepComplete
	* ループしたとき
* OnUpdate
* OnWaypointChange
	* DOLocalPath のwaypointを通過したとき

コールバックの実行順は渋谷ほととぎす通信に書いてあります。
[DOTweenのコールバック関数の実行順 - 渋谷ほととぎす通信](http://www.shibuya24.info/entry/2016/10/18/223000)



## Sequence

TweenMaxにはTimelineMaxがありますね。

DOTweenのSequenceはそんなに高機能ではありませんが、ひと通りそろっています。
ちょっとややこしい挙動(joinとdelay)があるので、一度試すのをオススメします。

```DOTween.cs
Sequence mySequence = DOTween.Sequence();
mySequence.Append(transform.DOMoveX(45, 1));

```

* Append(tween)
	* sequenceに追加。
* AppendInterval
	* Appendしたtweenにはdelayが利かないので、AppendIntervalで追加する
* Join(tween)
	* Joinすると、末尾にあるtween等と同時に実行する
	* Flasher用語で言うところのPararrelみたいなノリで使えるが、SetDelayがちょっとやっかい
		* AppendしたやつにSetDelay → Joinしたやつも遅れる
		* JoinしたやつにSetDelay → Appendした同時に実行するやつは先に実行、Joinしたやつは単独でSetDelayがかかる
	* 同時に実行されているtweenの一番長いやつが終わったら次のtweenに進む

![2016-12-16 02_22_30.gif](https://qiita-image-store.s3.amazonaws.com/0/2631/e22e5f13-63f3-831b-7b71-4f35ea024446.gif "2016-12-16 02_22_30.gif")
Sequenceを使った例


## その他

### timeScale

時間を早送りしたりスローモーションにしたりできるやつ。

TweenMax

* globalTimeScale でグローバルに変えたり
* 個別のTweenやTimelineのtimeScale()で変更できる


```DOTween.cs
DOTween.timeScale = 4f; // 4倍速 グローバル
myTween.timeScale = 0.5f; // 個別のtweenに対してスケール
sequence.timeScale = 1.5f; // 個別のSequenceにもできる
```

## よきTweenライフを！

![2016-12-16 21_29_10.gif](https://qiita-image-store.s3.amazonaws.com/0/2631/c1e4695b-42cb-a1b1-cb6a-d95457c3cc77.gif "2016-12-16 21_29_10.gif")