[Unity] DOTweenのSequenceを使ってアニメーションを結合する

## 実行環境
- Unity5.6.0b1 (beta)
- DOTween v1.1.310

## DOTweenについて
- 以下の記事にて紹介
  - [[Unity] DOTweenを使ってUI要素を点滅させる](http://qiita.com/lycoris102/items/fe148d2c6803742c6f4d)

## Sequenceを生成する

```c#:SequenceSample
using DG.Tweening;
using UnityEngine;

public class SequenceSample : MonoBehaviour
{
	void Start()
	{
	    Sequence sequence = DOTween.Sequence();
	}
}

```

## SequenceにTweenを結合する
結合するために使用する関数は以下の通り

|関数名||
|---|---|
|Append|Sequenceの最後にTween/Sequenceを追加する|
|Insert|指定した秒数後に再生開始するTween/Sequenceを追加する|
|Join|直前に追加されたTween/Sequenceと同時再生する|
|Prepend|Sequenceの最初にTween/Sequenceを追加する|

```c#:SequenceSample
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class SequenceSample : MonoBehaviour
{
    public CanvasGroup ResultCanvasGroup;
    public ParticleSystem Particle;

	void Start()
	{
	    Sequence sequence = DOTween.Sequence()
	        .OnStart(() =>
	        {
	            ResultCanvasGroup.alpha = 0.0f;
	            ResultCanvasGroup.transform.localScale = Vector3.one * 3.0f;
	        })
	        .Append(ResultCanvasGroup.DOFade(1.0f, 2.0f).SetEase(Ease.OutCubic))
	        .Join(ResultCanvasGroup.transform.DOScale(1.0f, 2.0f).SetEase(Ease.OutBounce));

	    sequence.Play();
	}
}
```

![sequence1.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/440c72d0-5b9f-ccb3-006e-03e26114d4c3.gif)

## Sequence実行中にTween以外の動作を実行する
Callback関数を使用する

|関数名||
|---|---|
|AppendCallback|Sequenceの最後にCallbackを追加する|
|InsertCallback|指定した秒数後に呼ばれるCallbackを追加する|
|PrependCallback|Sequenceの最初にCallbackを追加する|

- 例えば、以下のようなケースで使うと良さそう
  - アニメーションの途中で sprite を変更する
  - アニメーションの途中でパーティクルを発火する

```c#:SequenceSample
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class SequenceSample : MonoBehaviour
{
    public CanvasGroup ResultCanvasGroup;
    public ParticleSystem Particle;

	void Start()
	{
	    Sequence sequence = DOTween.Sequence()
	        .OnStart(() =>
	        {
	            ResultCanvasGroup.alpha = 0.0f;
	            ResultCanvasGroup.transform.localScale = Vector3.one * 3.0f;
	        })
	        .Append(ResultCanvasGroup.DOFade(1.0f, 2.0f).SetEase(Ease.OutCubic))
	        .Join(ResultCanvasGroup.transform.DOScale(1.0f, 2.0f).SetEase(Ease.OutBounce))
	        .InsertCallback(0.7f, () => Particle.Play()); // 再生0.7秒後に実行

	    sequence.Play();
	}
}
```

![sequence2.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/3d287dd5-b6cc-5989-922e-da0c65685551.gif)

## Sequence同士を結合する
- http://dotween.demigiant.com/documentation.php#creatingSequence
- `Sequences can be contained inside other Sequences without any limit to the depth of the hierarchy.`
- SequenceにはSequenceも結合可能
- 特定の条件の場合、再生する/しないを制御するのに役立つ

```c#:SequenceSample
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class SequenceSample : MonoBehaviour
{
    public CanvasGroup ResultCanvasGroup;
    public ParticleSystem Particle;
    public List<Image> StarImageList;
    public int Score = 2;

	void Start()
	{
	    Sequence mainSequence = DOTween.Sequence();
	    Sequence resultSequence = DOTween.Sequence()
	        .OnStart(() =>
	        {
	            ResultCanvasGroup.alpha = 0.0f;
	            ResultCanvasGroup.transform.localScale = Vector3.one * 3.0f;
	        })
	        .Append(ResultCanvasGroup.DOFade(1.0f, 2.0f).SetEase(Ease.OutCubic))
	        .Join(ResultCanvasGroup.transform.DOScale(1.0f, 2.0f).SetEase(Ease.OutBounce))
	        .InsertCallback(0.7f, () => Particle.Play());

        // スコア数だけAppendする
	    for (int i = 0; i < Score; i++)
	    {
	        mainSequence.Append(StarSequence(StarImageList[i]));
	    }

	    mainSequence.Prepend(resultSequence);
	    mainSequence.Play();
	}

    Sequence StarSequence(Image starImage)
    {
        return DOTween.Sequence()
            .OnStart(() =>
            {
                starImage.transform.localScale = Vector3.one * 3.0f;
                starImage.color = new Color(0.9f, 0.9f, 0.4f, 1.0f);
            })
            .Append(starImage.transform.DOScale(1.0f, 1.0f).SetEase(Ease.OutBounce));
    }
}
```

![sequence3.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/9886a1f4-ac6c-da08-da0a-961d3d3b8d87.gif)


## 待機時間を挟む
一定時間経過後に次のTween/Sequenceを実行したい場合は、Interval関数を使用する

|関数名||
|---|---|
|AppendInterval|Sequenceの最後に待機時間を追加する (単位:秒) |
|PrependInterval|Sequenceの最初に待機時間を追加する (単位:秒)|

```c#:IntervalSample
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

public class IntervalSample : MonoBehaviour
{
    public Image StarImage;

	void Start()
	{
	    Sequence fadeInSequence = DOTween.Sequence()
	        .Append(StarImage.DOFade(1.0f, 1.0f))
	        .Join(StarImage.transform.DOScale(1.0f, 1.0f))
	        .Join(StarImage.rectTransform.DORotate(new Vector3(0.0f, 0.0f, 360.0f), 1.0f, RotateMode.FastBeyond360));

	    Sequence fadeOutSequence = DOTween.Sequence()
            .Append(StarImage.DOFade(0.0f, 1.0f))
	        .Join(StarImage.rectTransform.DORotate(new Vector3(0.0f, 0.0f, -360.0f), 1.0f, RotateMode.FastBeyond360))
	        .Join(StarImage.transform.DOScale(3.0f, 1.0f));

	    Sequence sequence = DOTween.Sequence()
	        .OnStart(() =>
	        {
	            StarImage.transform.localScale = Vector3.one * 3.0f;
	            StarImage.color = new Color(
                    StarImage.color.r,
                    StarImage.color.g,
                    StarImage.color.b,
                    0.0f
	            );
	        })
	        .Append(fadeInSequence)
	        .AppendInterval(2.0f) // 2秒待機
	        .Append(fadeOutSequence);

	    sequence.Play();
	}
}
```

![interval_sample.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/c1c33160-44ff-f14d-c09d-57108dfdf523.gif)

## Sequence自体の再生時間を取得する
- Sequence.Duration() で取得出来る
- 公式Documentのサンプルにある通り、そのSequenceを横断する挙動を追加する際に使える (Insertにて Sequence.Duration() を指定)

```c#
// Insert a scale tween for the whole duration of the Sequence
mySequence.Insert(0, transform.DOScale(new Vector3(3,3,3), mySequence.Duration()));
```