渋谷ほととぎす通信

新しいこと、枯れたこと問わず大庭が興味を持ったものを調査、生活の効率を求める完全趣味の技術ブログ。基礎を大事にしています。

今一番個人的にアツいUnityのTweenエンジン『DOTween』スニペット集 〜Transform編〜


f:id:esakun:20150825162207p:plain:w450

私はUnityを使ってスマホゲームのUIの組み込み、バトルの設計、演出、実装と一通りアプリケーション周りを担当することが多く、その開発の中で特に使用しているアセットは、今回紹介するDOTweenです。

開発効率を何倍も上げ、プロダクトクオリティも一気にあげることができるDOTweenの魅力と伝えていきたいと思います。

DOTweenとは

DOTweenとはUnityで使用できるTweenライブラリです(無料。有料版もあり)。
UnityのTweenエンジンの中で私が最もオススメします。 正式な読み方が分からないですが、勝手に「ドットゥイーン」と呼称しています。

DOTweenとは前身であるHOTweenの改良版です。

DOTween is more than 400% faster

DOTween (HOTween v2)

HOTweenと比べて400%高速だと公式ページで謳っています。

私を含め、HOTweenの文法に慣れ親しんだ人にとっては、記述が大きく変わってしまったため、導入当初はとても戸惑うかもしれません。

しかし慣れてしまうとDOTweenの方が、かなりコード量を抑えることができ、見通しの良いコードになります。

その理由としては拡張メソッドの採用が大きいです。

DOTweenのHOTween的な書き方

// 1.2秒かけて(5, 0, 0)の位置に移動します
DOTween.To(() => transform.localPosition, 
            x => transform.localPosition = x,
            new Vector3(5f, 0, 0), 1.2f);

第1引数に操作したいプロパティのgetter、第2引数にsetter、第3, 4引数にゴールの値とかかる時間を

第1引数 第2引数 第3引数 第4引数
操作したい
プロパティの
getter
操作したい
プロパティの
setter
ゴールの値 時間

という風にコード量が多くなります。

DOTweenの拡張メソッド版

// 1.2秒かけて(5, 0, 0)の位置に移動します
transform.DOLocalMove(new Vector3(5f, 0, 0), 1.2f);

一方拡張メソッドを使うと、第1引数にゴール値、第2引数に時間と、シンプルで分かりやすいコードになります。
※内部的にはHOTween的な書き方の処理が呼び出されています

DOTween一択

よっぽどのことが無い限りHOTweenを使う理由はなくなりました。

  • 使用しているコアなライブラリがHOTweenを採用している
  • 既存プロジェクトがどっぷりHOTweenに使っている

このようなケースでは仕方ないかもしれません。

DOTweenの使い方

本記事ではDOTweenのショートコードを紹介するとともに、「こんな機能があったのね」という個人的な新発見を綴っていくシリーズです。

今回は使用頻度ナンバーワンのTransformコンポーネントの拡張メソッドについてまとめていきます。

※注意:これからのサンプルは以下のように `DG.Tweening` をusingしている必要があります。
using DG.Tweening;

DOTweenの基本形

Tweenと言えば移動や回転アニメーションをまず思い浮かべます。
DOTweenを使ってTransformコンポーネントの操作方法を紹介していきます。

平行移動 DOLocalMove

f:id:esakun:20150825150810g:plain

Transformクラスの拡張メソッドが定義されていると、transform.Hogehoge(); という形で実行することができるため、直感的に処理を読み書きすることが出来ます。

以下のサンプルは平行移動するだけのシンプルなコードです。

transform.DOLocalMove (new Vector3 (3f, 2, 0), 2f);

これをHOTweenで書きなおしてみると、

HOTween.To (transform, 2f, new TweenParams ()
    .Props ("localPosition", new Vector3 (3f, 2, 0));

となり、非常に長ったらしいコードとなってしまうのがお分かりになるかと思います。

またHOTweenはプロパティ名を文字列指定しないといけないため、タイプミスによるバグが発生しやすいのも良くない点でしたが、DOTweenはタイプセーフで安全です。

第一引数に移動先のゴールを指定しますが、以下のようにVector3型ではなく、x, y, zを個別に指定することも出来て至れり尽くせりです。

transform.DOLocalMoveX (-3f, 2f);

y, z軸はそのままで、x軸のみ平行移動することが出来ます。

回転 DOLocalRotate

transform.DOLocalRotate (new Vector3 (120f, 0, 0), 2f);

2秒かけてx軸を120度に回転させます。

あわせて読みたい
DOTweenで360度回転させたい時、必要な設定をし忘れて少しハマる時があります。そんな時はこちらの記事をどうぞ。
DOTweenで360度くるくる回転させたい - 渋谷ほととぎす通信

拡大縮小 DOScale

transform.DOScale (new Vector3 (3f, 4f, 5f), 2f);

2秒かけて拡大させます。

イージング

トゥイーンといえばイージングが欠かせません。

transform.DOLocalMoveX (-3f, 2f).SetEase(Ease.OutQuart);

SetEase関数を指定すると加速度を設定できます。
DOTweenはデフォルトの加速度を設定できます。何もしなければ Ease.OutQuad が指定されます。

以下の種類が実装されています。

Linear,
InSine,
OutSine,
InOutSine,
InQuad,
OutQuad,
InOutQuad,
InCubic,
OutCubic,
InOutCubic,
InQuart,
OutQuart,
InOutQuart,
InQuint,
OutQuint,
InOutQuint,
InExpo,
OutExpo,
InOutExpo,
InCirc,
OutCirc,
InOutCirc,
InElastic,
OutElastic,
InOutElastic,
InBack,
OutBack,
InOutBack,
InBounce,
OutBounce,
InOutBounce,
Flash,
InFlash,
OutFlash,
InOutFlash,

トゥイーンの停止

トゥイーンの停止には2通りあります。

  1. 中断
  2. 最後まで到達させて終了

トゥイーンの中断

中断とは、ゴール地点までトゥイーンせず中断実行した時点で停止することを指します。

Tweenインスタンスを保持して中断

var tw = transform.DOLocalMoveX (-3f, 2f);
if (tw != null){
    tw.Kill();
}

DOTweenを実行するとTweenインスタンスが戻り値として帰ってきます。このんインスタンスに対し、Killを実行するとTweenは中断します。
この場合ですと、平行移動しているTweenが中断されます。

ターゲットに対して一括中断

transform.DOLocalMoveX (-3f, 5f);
transform.DOScale (new Vector3 (3f, 4f, 5f), 4f);
transform.DOLocalRotate (new Vector3 (120f, 0, 0), 2f);

transform.DOKill();

transformに対して平行移動、回転、拡大縮小を同時にTweenさせています。DOKillを実行したら、全てのTweenが中断されます。

最後まで到達させて終了

先ほど中断でKillメソッドを使用しましたが、今回はCompleteメソッドを使用します。

var tw = transform.DOLocalMoveX (-3f, 2f);
if (tw != null){
    tw.Complete();
}
transform.DOLocalMoveX (-3f, 5f);
transform.DOScale (new Vector3 (3f, 4f, 5f), 4f);
transform.DOLocalRotate (new Vector3 (120f, 0, 0), 2f);

transform.Complete();

Killとの違いはゴール地点まで一気に到達させてトゥイーンを終了させることです。
これを利用して、演出のスキップなどを実装することが多いです。

トゥイーンのループ設定

transform.DOLocalMoveX (-3f, 5f).SetLoops(-1, LoopType.Yoyo);

SetLoops関数を使うと、トゥイーンをループさせることができます。

第一引数 第二引数
ループ回数 ループの種類

ループ回数は-1を代入すると無限ループに入ります。停止させるためにはKillを実行します。Completeでは止まりません。

あわせて読みたい

少し特殊なトゥイーン

ここからは少し特殊で複雑な動きの処理を紹介していきます。

複数座標移動

第一引数にVector3型の配列を渡し、各座標を順番に通るという複数座標移動が提供されています。

f:id:esakun:20150825152108g:plain

transform.DOLocalPath (
    new Vector3[]{ 
       new Vector3 (3f, 3f), 
       Vector3.zero, 
       new Vector3 (-3f, 2f) 
     }, 2f, PathType.CatmullRom);

第三引数のPathTypeCatmullRomにするか、Linearにするかで大きく印象が変わります。

CatmullRom

なめらかなカーブを補完してくれます。 ※上のサンプルはこのCatmullRom曲線を指定しています。

Linear

直線的な移動をします。

デフォルト引数ではLinearになっていますので、なめらかなカーブをさせたい場合は、CatmullRomをセットしてみてください。

f:id:esakun:20150825153039g:plain

このようにどういう軌跡を辿かはGizmosで表示可能です。
※軌跡の色は第六引数で変更可能

パンチング運動 (平行移動)

後で紹介するシェイクと似ていますが、移動するベクトル範囲を指定する所が特徴です。

f:id:esakun:20150825154129g:plain

transform.DOPunchPosition (new Vector3 (5f, 0f), 2f, 10, 1f);

パンチング運動 (拡大縮小)

f:id:esakun:20150825154554g:plain

transform.DOPunchScale (new Vector3 (3f, 3f, 3f), 3f, 3, 0);

他にDOPunchRotate(回転パンチング)があります。

シェイク

パンチングと違い、ランダムな移動を繰り返します。
カメラに適用して、衝撃の揺れ演出をするときに役立ちそうです。

f:id:esakun:20150825161102g:plain

transform.DOShakePosition (2f);

DOShakePosition(平行移動)以外に、DOShakeRotation(回転)DOShakeScale(拡大縮小)が提供されています。

シンプルなジャンプ

この記事を書きながら知ったのですが、ジャンプ運動をさせることが出来ます。ただ指定するプロパティ的にあまり複雑なジャンプは難しそうです。
あまり重要でないときや、モック時にサクっと実装できて良いかもくらいに捉えておくと良いかもしれません。

f:id:esakun:20150825150358g:plain

transform.DOJump (new Vector3 (-3f, 0, 0), 3, 3, 3f).SetEase (Ease.Linear);
あわせて読みたい
https://cdn-ak.f.st-hatena.com/images/fotolife/e/esakun/20161220/20161220013955.gif
DOTweenとAnimatorを使った巻き戻し表現を作ってみました。
DOTweenとAnimator組み合わせの巻き戻しと早送り実装 - 渋谷ほととぎす通信

ゴール値ではなく初期値を使う方法

今までのサンプルは以下のように第1引数にゴール地点を代入していました。

transform.DOLocalMoveX (3f, 1.5f);

ゴール値ではなく初期値を代入して現在の状態にアニメーションさせる方法もあります。

// 現在の座標がx:0だった場合
transform.DOLocalMoveX (3f, 1.5f).From();

このようにFrom関数を実行すると、(x : 3)からアニメーションが始まり、現在座標(x : 0)にアニメーションします。
知ってて損はないテクニックです。

まとめ

クライアントエンジニアにとってTweenはプロダクトに命を吹き込む大事な道具です。
今回は使用頻度高めのTransformに限った内容で紹介してきました。

とても簡単な印象を持たれたのではないでしょうか。
DOTweenを知ってしまった今は他のエンジンを使う気になりません。

Transform以外のTweenもやりたい!!!

f:id:esakun:20150914000034g:plain

例えば文字列をTweenさせることもDOTweenでは簡単に実装可能です。

こちらの記事で紹介していますので、是非読んでみてください。眺めるだけでも雰囲気がつかめると思います。

こちらのDOTween関連記事もあわせてどうぞ

開発環境

  • Unity5.3.6f1(追記 : Unity2019.1段階でも問題なく動きます)
  • DOTween v1.1.310

参考図書


少しお高めの本ですが、アニメーションを深掘りする第1歩として役に立った本でオススメです。