Unityのアニメーション方法検討（Animator, SimpleAnimation, DOTween）

#概要
Unityのバージョンは2018.4

以下の記事でアニメーションの管理どうするか書いたが
https://qiita.com/seka/items/f7530c30d8aaf11b1790
ここでは Animator と SimpleAnimation と DOTween の使用方法と使ってみての感想をメモ。

#Animator
Unityの標準機能である Animator はアニメーションファイルを作ると勝手に作られる

 - 作ったアニメーションがデフォルトのアニメーションとして再生される（ループするようになっているのでAnimationファイルのLoopTimeをfalseにする）
 - AnimationウィンドでPreviewの下のアニメーション名をクリックすると別のアニメーションを作成できる
 - Animatorウィンドウにアニメーションが複数ある状態で Any State を右クリック > Make Transitions > 繋がってないアニメーションを選択（矢印が生成される）
 - Animatorウィンドウの左上のParametersで値を追加し、アニメーション同士の矢印をクリックしConditionsにアニメーションが切り替わる条件を追加できる

アニメーションをスクリプトで再生（以下はサンプル）

```.cs

    // アニメーションを再生
    this.GetComponent<Animator>().Play("ImageAnimation");

    // 再生中のアニメーションファイル名を取得
    AnimatorClipInfo[] clipInfo = this.GetComponent<Animator>().GetCurrentAnimatorClipInfo(0);
    string name = clipInfo[0].clip.name;

    // Parameters を変更
    // Image1の値がtrueになった時にアニメーションが変わるようにConditionsに条件を追加しておく
    this.GetComponent<Animator>().SetBool("Image1", true);
```

使ってみた感想

- Playでアニメーションを切り替えるだけならそれほど難しくない
- Animator の Layers, Parameters や Transitions, 各stateのInspector設定 などを使いだすと変更と管理がだいぶ面倒

参考ページ

- https://styly.cc/ja/tips/animator_controller/
- https://yttm-work.jp/unity/unity_0018.html
- https://light11.hatenadiary.com/entry/2019/04/11/005147
- https://gametukurikata.com/animationanimator/animatorstate

#SimpleAnimation
Unity Technologies社が提供しているアセット
https://github.com/Unity-Technologies/SimpleAnimation
Animatorは状態遷移が増えすぎるとステートマシンが複雑になり管理しにくくなる
SimpleAnimationはステートマシンでの管理をせずにスクリプトで管理する

使い方

- オブジェクトの Add Component > Scripts > Simple Animation を選択
- Asset > 右クリック > Create > Animation を選択
- 作成した Animation を Simple Animation の Animation にセット
- 複数 Animation を管理する場合は Animations > Size を変更する
- Element が増えるのでそこに別の Animation をセットする（左のDefault(1)はアニメーションの名前）
- Play Automatically のチェックを外すと自動で再生しなくなる
- Animate Physics と Culling Mode は変更すると Animator の Update Mode と Culling Mode が変わる
- Animationウィンドでアニメーションを作る（Previewの下のアニメーション名をクリックすると編集するアニメーションを切り替えらえる）

アニメーションをスクリプトで再生（以下はサンプル）

```.cs

    SimpleAnimation simpleAnima = this.GetComponent<SimpleAnimation>();

    // デフォルトアニメーションを再生
    simpleAnima.Play("Default");

    // 停止
    simpleAnima.Stop();

    // Anima1アニメーションをクロスフェードで再生
    simpleAnima.CrossFade("Anima1", 0.1f);
```

使ってみた感想

- Animator の操作がないので管理がだいぶらく
- Animation ウィンド（特にアニメーションカーブ）を使いこなせればこれで十分（DOTweenはいらないかも）
- Animation は再生途中の特定のタイミングでメソッド呼ぶことできるので、キャラが殴った時に音を再生するといったことが簡単に実装できる
- Textのアニメーションもできなくはない
  - スコアを [SerializeField] private int score = 0; と宣言する
  - アニメーションで score の値を変化するようにする（Editor上で score を変更）

参考ページ

- https://kan-kikuchi.hatenablog.com/entry/SimpleAnimation
- https://qiita.com/yamachan360/items/38b76a67ee0faef7e6b0

#DOTween
ダウンロードは以下（使用したのはFREE版）
https://assetstore.unity.com/packages/tools/animation/dotween-hotween-v2-27676

インポートすると以下の場所で設定ができる
Tools > Demigiant > DOTween Utility Panel

Preferences タブ は以下のように設定してテストした

- AutoPlay > None
- AutoKill > false  

アニメーションはスクリプトで書く（以下はサンプル）

```.cs

    using DG.Tweening;

    // オブジェクトをローカル座標を基準に移動（移動先, 時間）
    this.gameObject.transform.DOLocalMoveY(100.0f, 1.0f)
    
    // オブジェクトのスケール変更（スケール, 時間）
    this.gameObject.transform.DOScale(2.0f, 1.0f)
    
    // オブジェクトの回転（座標, 時間）
    this.gameObject.transform.DORotate(new Vector3(90.0f, 0.0f), 1.0f);

    // オブジェクトの移動（座標, 時間）
    Tween animaTween = this.gameObject.transform.DOMove(Vector3.one, 1.0f);
	
    // Tweenアニメーションを設定
    animaTween.SetEase(Ease.InOutCirc);
    
    // ループ回数
    animaTween.SetLoops(2);
    
    // 再生開始前の待機時間
    animaTween.SetDelay(1.0f);

    animaTween.OnStart(() => {
    	// 開始時に呼ばれる
        // 一度終了した後に再スタートしたときは呼ばれない
    	Debug.Log("Start");
    });
    animaTween.OnRewind(() => {
    	// 再スタート時に呼ばれる
        // 逆再生したときは終了時に呼ばれる
    	Debug.Log("Rewind");
    });
    animaTween.OnUpdate(() => {
    	// 値が更新されると呼ばれる
    	Debug.Log("Play");
    });
    animaTween.OnComplete(() => {
    	// 終了時に呼ばれる
    	Debug.Log("End");
    });


    // 再生開始（停止からの再開）
    animaTween.Play();

    // 一時停止
    animaTween.Pause();
    
    // 再スタート
    animaTween.Restart();
 
    // 逆再生
    animaTween.PlayBackwards();

    // 終了
    animaTween.Complete();
 
    // 破棄（破棄すると再スタートなどはできない）
    animaTween.Kill();


    // アニメーションを順番に再生
    Sequence seq;
    seq.Append(this.gameObject.transform.DOMove(Vector3.one, 1.0f));
    seq.Append(this.gameObject.transform.DOMove(Vector3.zero, 1.0f));
    seq.Play();

    // アニメーションをミックスして再生
    seq.Join(this.gameObject.transform.DOMove(Vector3.one, 1.0f));
    seq.Join(this.gameObject.transform.DOScale(2.0f, 1.0f));
    seq.Play();

    // Textのスコアを徐々に上げる
    int score = 0;
    var text = GameObject.Find("Text").GetComponent<Text>();
    DOTween.To(
    	() => score,
        num => { score = num; text.text = score.ToString(); },
        1000,                 // MAX値
        1.0f                  // アニメーション時間
    );
```

使ってみた感想

- Tweenのアニメーションを使えるので滑らかなオブジェクトの移動などが簡単にできる
- アニメーションをつなげたりミックスしたりも割と簡単
- テキストの値をアニメーションするに便利
- 終了時に何か処理を実行させるのもUnityのAnimationよりやりやすい（再生中の特定のタイミングで何か実行するのは向かないかも）
- キャラクターのアニメショーン変更や移動などには向いてない（Animatorの方がいい）

参考ページ

- https://amagamina.jp/how-to-dotween/
- https://www.tempura.blog/entry/2019/03/02/233523
- https://qiita.com/loveRice/items/d2dcc1cd67ee1a6998f3
- https://qiita.com/kagigi/items/bdf4d42835add07b0077
- https://qiita.com/3panda/items/0a8c93645087b6b6d728