DOTweenを使ってskip可能なアニメーションを作る

#環境
Unity：5.3.7p4
DOTween：1.1.575

#はじめに
skip可能なDOTweenアニメーションを作成することが多かったのでまとめておきます。UIはuGUIです。
仮のアニメーションということで経験値取得ダイアログのワイヤーフレームを作ってみました。
![FullSizeRender 2.jpg](https://qiita-image-store.s3.amazonaws.com/0/44990/c598de96-d37f-1a23-e12d-213379f0f817.jpeg)

#先にまとめ
```
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

public class GetExpSample : MonoBehaviour
{
	// ダイアログ
	[SerializeField]
	GameObject m_expDialog;
	// 経験値バー
	[SerializeField]
	Slider m_expSlider;
	// 経験値テキスト
	[SerializeField]
	Text m_expText;
	// 経験値GETボタン
	[SerializeField]
	GameObject m_getExpButton;
	// 画面全体を覆うskipボタン
	[SerializeField]
	GameObject m_skipButton;
	// 閉じるボタン
	[SerializeField]
	GameObject m_closeButton;

	// 現在の経験値 サンプルなので固定
	int m_currentExp = 0;
	// レベルアップに必要な経験値 サンプルなので固定
	int m_maxExp = 1000;

	void Start()
	{
		m_expDialog.SetActive(false);
		m_skipButton.SetActive(false);
	}
		
	/// <summary>
	/// 経験値を取得する
	/// </summary>
	/// <param name="gotExp">取得した経験値</param>
	void GetExp(int gotExp)
	{
		float addSliderValue = (float)gotExp / (float)m_maxExp;
		float resultSliderValue = m_expSlider.value + addSliderValue;

		// メーターを増加する演出
		float getExpAnimTime = 2f;
		Sequence m_sequence = DOTween.Sequence().
			OnStart(() => {
				m_getExpButton.SetActive(false);
				m_skipButton.SetActive(true);
				m_expDialog.SetActive(true);
				m_expDialog.transform.localScale = Vector3.zero;
				m_closeButton.SetActive(false);
				m_expText.text = gotExp.ToString();
				}).
			Append(m_expDialog.transform.DOScale(Vector3.one, 0.2f)).
			AppendInterval(0.2f).
			Append(DOTween.To(
				() => gotExp,							// 開始値
				exp => m_expText.text = exp.ToString(),	// 値を更新する
				0,										// 最終値
				getExpAnimTime							// アニメーション時間
			)).
			Join(DOTween.To(
				() => m_expSlider.value,				// 開始値
				value => m_expSlider.value = value,		// 値を更新する
				resultSliderValue,						// 最終値
				getExpAnimTime							// アニメーション時間
			)).
			AppendInterval(0.2f).
			OnComplete(() => {
				m_getExpButton.SetActive(true);
				m_skipButton.SetActive(false);
				m_closeButton.SetActive(true);
				m_expSlider.value = resultSliderValue;
				m_expText.text = "0";

			});
		m_sequence.Play();
	}

	/// <summary>
	/// 演出中画面タップ
	/// </summary>
	public void OnScreenTap()
	{
		// sequenceを切りつつ、OnCompleteを呼ぶ
		DOTween.KillAll(true);
	}

	/// <summary>
	/// 閉じるボタンタップ
	/// </summary>
	public void OnCloseButton(){
		m_closeButton.SetActive(false);
		m_expDialog.transform.DOScale(Vector3.zero, 0.1f);
	}

	/// <summary>
	/// 経験値取得ボタンタップ
	/// </summary>
	public void OnGetExpButton()
	{
		GetExp(200); // 仮に200exp取得する
	}
}
```

![skip.gif](https://qiita-image-store.s3.amazonaws.com/0/44990/e31672f3-e148-679f-9cbc-42e63e69f1e2.gif)

#解説
####Sequenceを破棄しつつOnCompleteを呼ぶ
経験値GETボタンタップ時に画面全体を覆う透明なskipボタンをActiveにしています。
skipボタンタップでSequenceをKillし、その際にOnCompleteを呼び出しています。

```
	/// <summary>
	/// 演出中画面タップ
	/// </summary>
	public void OnScreenTap()
	{
		// sequenceを切りつつ、OnCompleteを呼ぶ
		DOTween.KillAll(true);
	}
```
なので、OnCompleteにはアニメーション終了時と同じ状況になるように各GameObjectやvalueを設定するよう記述しています。

####特定のアニメーションのみをskipしたい場合
今の書き方だと全てのtweenを破棄します。
tweenを特定したい場合はIdを指定すると良いです。

```
	void GetExp(int gotExp)
	{
		...
		Sequence m_sequence = DOTween.Sequence().
			SetId("getSequence").	// idを設定する
			...
	}
	...

	public void OnScreenTap()
	{
		// 特定のidのtweenを全て破棄しつつ、OnCompleteを呼ぶ 
		DOTween.TweensById("getSequence").ForEach((tween) => tween.Kill(true));
	}

```
または、Sequenceをメンバー変数にしても特定できます。

```
m_sequence.Kill(true);
```

####Sequenceを破棄したくない場合
sequenceは使いまわすからとっておいて、アニメーション終了&OnCompleteだけ呼び出したい時。

```
m_sequence.Complete(true);
```

#さいごに
skipするためだけの仮の演出を作り始めたのですが、レベルアップ演出を挟むには...とか、SEとテクスチャをあてたいな...とか、想定していなかったことを始めそうでした。
何かの学習と絡めてレベルアップダイアログ出せるようにしたいなぁ。
あと、Hierarchyってどう共有すれば良いんでしょう？