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

前回：[DOTween完全に理解するその3 UIアニメーション編](https://qiita.com/BEATnonanka/items/fd0e8fbfc63992b865cb)

#今回解説するアニメーション
今回はTweenの中でも特殊なアニメーション
DOPathについて解説します。

DOPathはオプションで様々な挙動をさせることができるので
その分覚えることはたくさんありますが、上手く使えばとても強力なアニメーションです。

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

# DOPath/DOLocalPath
![movePath1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/986d94ef-3819-a3b1-1030-0b8238407e7f.gif)![movePath2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/621d5a85-edbc-5ec8-e4f2-59bd19537ada.gif)

```c#
var doPath = transform.DOPath(path, duration);
var doLocalPath = transform.DOLocalPath(path, duration);
```
pathは```Vector3[]```です。
目的座標（WayPoint）を指定して、そこに向けて移動するアニメーションを作成できます。
上のgifは全て同じ座標をpathとして指定しています。
SetOptionを使用することで終点から始点を繋げるかどうかを指定できます。(後述)
初期位置は自動でWayPointに含まれる為、追加したのは右上・右下・左下の３箇所です。

## SetOption
```c#
doPath.SetOptin(closePath, lockPosition, lockRotation)
```
closePath=trueに設定すると**「最後のWayPoint→最初のWayPoint」が繋がるようになります**
またlockPositionやlockRotateionはそのままの意味で、
軸の移動や回転を```AxisConstraint```を使用して軸ごとに制限することができます。
AxisConstraintは「|」で繋ぐことで複数の軸に対して制限をかけることができます。

```C#
lockPosition = AxisConstraint.X;                    //座標のX軸を固定する
lockRotation = AxisConstraint.Z | AxisConstraint.Y; //回転のZ,Y軸を固定する
```
※lockPositionとlockRotationは今回使用していません。

## PathType
DOPath生成時にどういったPathの使い方をするかを指定することができます

```C#
var doPath = transform.DOPath(path, duration, pathType);
```
|PatyType|説明|
|----|------|
|Linear|シンプルにWayPoint同士を直線で繋ぐ|
|CatmullRom|WayPoint同士を曲線で繋ぐ|
|CubicBezier|ベジェ曲線を生成する|

### CatmullRom
![catmullRom.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/b95b0025-75ef-179f-2109-241971d5e9af.gif)
上のgifはDOLocalPathdで同じPathを指定していますが、挙動が違うことが確認できます。

### CubicBezier
![bezier1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/ca00db02-0596-6a7c-b247-39b02b8d437a.gif)
通常のpath指定とは違い**「WayPoint, ControlPointA, ControlPointB」**と設定する必要があります。
![dotween_path_cubicBezier.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/8722152a-0fc3-3904-9ee5-5828511c85a5.png)
これは[公式ドキュメント](http://dotween.demigiant.com/documentation.php)にある画像です。
**ControlPointAはTransformの現在値が対象になります。**

## SetLookAt
他にDOPath特有のオプションとして```SetLookAt()```があります。
このオプションが非常にクセが強く他の設定に影響を受ける為
しっかりと理解して使用する必要があります。
公式ドキュメントにも注意文が載っていますが、
**SetLookAtはDOPath生成直後か、SetOptionの直後に設定しなければなりません。**
**間に他の設定が入ると挙動が保証されなくなるようです（未検証）**

```C#            
doPath.SetLookAt(Vector3, forwardDirection, up);   //指定した座標を見る
doPath.SetLookAt(Transform, forwardDirection, up); //指定したTransformの座標を見る
doPath.SetLookAt(float, forwardDirection, up);     //進行方向を見る
```
forwardDirectionとupは省略可能です。
forwardDirectionは正面方向を、upは頭上方向を設定可能です。
それぞれターゲットへの向きを計算する際に参照されます。

### SetLookAt(Vector3/Transform)
この二つは単純に「設定されたターゲットの方向を向く」設定を行います。
![lookAt2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/12b16d64-6b47-1797-9a82-9dd68c70070f.gif)


### SetLookAt(float)
こちらがかなり曲者で「進行方向を見る」という表現が正しいのかはわかりませんが、
そんな感じなのです...
この挙動に関してはgifをみてもらうのが良いかと思います。

0を設定すると次のWaypointに向かう時にその方向に向きます。
1に近い値に設定すると進行方向とは逆の向きを向くようになりますが、
**1にすると向きが変更されなくなってしまいます。**
![lookAt1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/9c0ebf38-0306-f8db-0525-2bd34198a9d2.gif)

## PathMode
Tween作成時に指定できるPlayModeは上記の**LookAtの挙動に影響を与えます。**

```C#
var doPath = transform.DOPath(path, duration, pathType, pathMode);
```
PathModeの設定が個人的には**非常に扱いが難しいと思っています。**
DOPathの用途に合わせて正しいPathModeを設定する必要があります。

まずそれぞれの動きを見てみましょう

### Full3D
![pathmode1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/27d2504c-6bf5-11ef-baaa-4d74436e7d8c.gif)
XYZ全ての座標移動をするPathを作成いてみました。
Full3Dは普通に3Dで動かす分にはほとんど問題ありません。
**ただ2D的に動かす場合は他の2つのどちらかを使うことをお勧めします。**
理由としてはデフォルトが正面方向がZ軸の正方向であることもありますが、
**SetLookAt(0)を設定していた場合、思った通りに回転を行ってくれない場合があります。**

### TopDown2D/Sidescroller2D
![pathmode2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/66021d99-b520-e47e-3aae-049175a588c2.gif)
赤,緑,青のBOXをX,Y,Z軸に見立てて、PathMode以外同じ設定で動かしています。
3D(Full3D)は前述の通りZ軸がforwardDirectionとなっています。
注目して欲しいのは右から左へ移動している時のTopDownとSide(Sidescroller2D)です。
**TopDown2DはZ軸のみの回転を行いますが、**
**Sidescroller2DはZ軸とY軸で回転を行い「Y軸が下を向かないような挙動」を行います**

![pathmode3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/93a8a56c-3462-6d2f-54bb-e541b1e35d6d.gif)
単純に左右に移動する場合にその差が顕著にでます。

PathMode名のそのままの意味ですが、
TopDown2Dは**トップダウン視点の2Dゲーム向けのアニメーションで、**
Sidescroller2Dは**横スクロールの2Dゲーム向けのアニメーションです。**

|PathMode|説明|デフォルトforward|デフォルトup|デフォルトで回転する軸|
|----|----|----|----|----|
|Ignore|LookAtを設定していても何もしない|なし|なし|なし
|Full3D|向きを決める際にシンプルな回転を行う|Z方向|Y方向|X,Y,Z
|TopDown2D|トップダウン式の回転を行う|X方向|Y方向|Z
|Sidescroller2D|サイドスクロール式の回転を行う|X方向|Y方向|Y,Z


#まとめ
今回はDOPathのみを取り上げて解説を行いました。
特にSetLookAt(float)とPathMode周りはドキュメントを読んでも理解できず、
しかも検証自体サイズ１のBoxで見ていたせいで回転の性質に気づくのに時間がかかりました。

DOPathは特にPathTypeをCubicBezierにすると色々面白い挙動ができます。
シーシャルゲームでよくあるドロップがUIにカーブしながら飛んでいく動きなんかも簡単に作れるかと思います。

Easeを使って緩急をつけるのもいいですが、曲線も簡単にリッチに見えるのでいいですね。