UIデザイナーがUnityのAnimator Controller使ってみた

![eyecatch_AdventCalendar2018_24.png](https://qiita-image-store.s3.amazonaws.com/0/108458/6dd96c33-0945-37d2-035f-d5fe0b3633bc.png)
これは [ドリコム Advent Calendar 2018](https://adventar.org/calendars/3421) の24日目です。
23日目は 西村 拓也 さんによる、 [副業ダヨ！出版までの軌跡](https://tech.drecom.co.jp/book6755/)です。

##はじめに
はじめまして、ドリコムでデザイナーをやっているカナサキです。
普段の業務ではモバイルゲームのUIデザインとレイアウトの実装を行っています。

デザイナーのみなさん、普段アニメーションってどのように作っていますか？
ゲームのアニメーションって条件によって分岐があったりして作るの面倒ですよね。
私は確認しながら作成・調整したいと常々思ってました。

今回は**UIアニメーションの条件分岐**の実装でUnityのAnimator Controllerを使った話をします。

キャラクターのモーション分岐でよく使われている機能ですが、UIのアニメーションでも使えるし、クライアントエンジニアさんも楽になるらしいので使えると便利で楽しいです！

##下準備
ゲームによくあるリザルト画面につけてみようと思います。
![リザルト1221.gif](https://qiita-image-store.s3.amazonaws.com/0/108458/c467acc0-0896-27d9-4fa7-f1327c7f203c.gif)

**:writing_hand_tone2:　大まかな流れ**
![リザルト遷移図.png](https://qiita-image-store.s3.amazonaws.com/0/108458/d38b30c2-47ba-1dac-26fb-fd494285794b.png)
この流れだと「初回クリア報酬」と「プレイヤーLvアップ」の条件分岐が必要になりそうです。
また、リザルトアニメーション中に画面タップでアニメーションの最後にスキップさせたいのでその分岐もいれたいと思います。

**:film_frames:　用意するアニメーションデータ**
![07.png](https://qiita-image-store.s3.amazonaws.com/0/108458/b80f07af-30da-2faf-993d-25358cadcbd0.png)

||        内容        |アニメーションデータ|
|:-:|:-------------------|:----------------------------|
| 1 |リザルト画面フェードイン   |Result_FadeIn.anim           |
| 2 |初回クリア報酬          |Result_SPClearReward.anim   |
| 3 |経験値（EXP）獲得       |Result_GetEXP.anim           |
| ４ |プレイヤーLvアップ       |Result_PlayerLvUP.anim       |
| 5 |獲得スコア             |Result_Score.anim            |
| 6 |ランク                |Result_Rank.anim             |
| 7 |リザルト終了タップ待ち    |Result_EndIdle.anim          |
| 8 |リザルト画面フェードアウト  |Result_FadeOut.anim          |

**:film_frames:　上記を制御するAnimator Controller**
![スクリーンショット 2018-12-20 14.49.44.png](https://qiita-image-store.s3.amazonaws.com/0/108458/8fb07eb4-213d-48fc-e0e0-51a016b66d5c.png)　`Result.Controller`
任意のフォルダにコントローラーとアニメーションデータを追加します。

##Animator Controllerにアニメーションデータを追加する
各アニメーションを繋げるために、Animator Controllerに読み込ませます。
Window＞Animation＞Animator
を選択するとAnimator Controller画面が表示されます。
![スクリーンショット 2018-12-18 18.16.52.png](https://qiita-image-store.s3.amazonaws.com/0/108458/ccc55588-355b-2c2f-fb5a-12c79dc05ed5.png)

Projectタブから先程追加した`Result.Controller`を選択します。
![スクリーンショット 2018-12-18 18.04.12.png](https://qiita-image-store.s3.amazonaws.com/0/108458/dd8ee5be-64dd-27ee-3957-6b17561c1d03.png)

するとAnimatorタブの表示がこのようになります。
色がついた長方形は「ステート（状態）」と呼びます。
![スクリーンショット 2018-12-18 18.19.49.png](https://qiita-image-store.s3.amazonaws.com/0/108458/bb8b1895-ec8f-6446-376b-454fe33f6914.png)

先程のアニメーションデータを選択してドラッグ＆ドロップするとコントローラーにステートが追加されます。
![スクリーンショット-2018-12-19-21.31.19.png](https://qiita-image-store.s3.amazonaws.com/0/108458/d4c80c3c-3a83-46bd-0c84-4bfe6a691b8c.png)

リザルトアニメーションの一連の流れを想像しながらステートの配置を調整します。
![スクリーンショット 2018-12-19 21.49.22.png](https://qiita-image-store.s3.amazonaws.com/0/108458/c473c505-c682-7f05-c14d-055387dede11.png)
ここで`Result_EndIdle`がオレンジ色になっているのが気になると思います。
オレンジは「デフォルトステート」と呼ばれるもので、初期状態が設定されているべきです。

この場合、リザルトの後半部分が初期状態として設定されてしまっているので、`Result_FadeIn`ステートに変更します。
`Result_FadeIn`ステートを選択し右クリックから`Set as Layer Default State`で変更されます。
![スクリーンショット 2018-12-18 18.54.49.png](https://qiita-image-store.s3.amazonaws.com/0/108458/a832f695-b1b6-87f6-df34-0b0c023ebf20.png)
初期状態を設定したら、あとはアニメーションの流れにそって各ステートから`Make Transition`で遷移を繋いでいきます。
![スクリーンショット 2018-12-18 19.03.05.png](https://qiita-image-store.s3.amazonaws.com/0/108458/0e865764-53bb-46cf-89db-8e95a35b5df2.png)
白い矢印が遷移する方向を示しています。
全部繋げるとこんな感じになりました。
![スクリーンショット 2018-12-19 22.19.37.png](https://qiita-image-store.s3.amazonaws.com/0/108458/1489c064-b71c-81c5-d9cd-5540500c4cf5.png)
おっと！スキップの分岐を忘れていました。
![Transition.png](https://qiita-image-store.s3.amazonaws.com/0/108458/0982ef7e-9274-8b28-73bb-2ba873b47485.png)
ごちゃっとなっちゃった・・・これでスキップの分岐もできました。

##Animator Controllerで条件分岐を設定する
そして、ここから楽しい条件分岐の設定をします！
`Result_FadeIn`ステートから矢印が２本出ているので、どのステートにいくか条件を設定します。
![00.png](https://qiita-image-store.s3.amazonaws.com/0/108458/b6e51187-0564-88b6-73bf-1b9969da2cdc.png)
分岐の条件は**「初回クリア報酬」が獲得できる or できない**

どちらかに遷移させたいのでAnimatorの「Parameters」タブの「＋」から`Bool`を選択します。
`Bool`は、「真 = true」と「偽 = false」の判定ができます。
![スクリーンショット 2018-12-18 19.17.28.png](https://qiita-image-store.s3.amazonaws.com/0/108458/e1a29b39-6187-9a64-fbae-757c67cc4e66.png)

`Bool`に対して名前が設定できるので`SpecialReward_Get`という名前を付けます。
![スクリーンショット 2018-12-19 9.59.39.png](https://qiita-image-store.s3.amazonaws.com/0/108458/d8b17957-301c-a550-2be7-659045b2d233.png)

初回クリア報酬を獲得したときは「真 = true」として、
専用演出`Result_SPClearReward.anim`を再生したいのでTransitionに以下を設定します。
![01.png](https://qiita-image-store.s3.amazonaws.com/0/108458/736647d1-6699-603d-a2cc-7848c6320937.png)
これで`SpecialReward_Get`が「True」のとき、`Result_SPClearReward.anim`を再生する設定になりました。

逆に**「初回クリア報酬」がないとき**はスキップさせたいので遷移を「偽 = false」に設定します。
![スクリーンショット 2018-12-19 11.13.33.png](https://qiita-image-store.s3.amazonaws.com/0/108458/4eb3a9d2-9ae8-967b-1bbb-031027430a51.png)
**プレイヤーレベルアップ**のアニメーションも同様に`Bool`で設定しました。

ちなみに・・
`Has Exit Time` のチェックがONになっていると**「Exit Time」に指定してる回数分遷移元のアニメーションを再生して次のステートへ行く**という命令になります。ここではフェードインアニメを流してから遷移したいのでONにしました。（もちろん１回です）
![02.png](https://qiita-image-store.s3.amazonaws.com/0/108458/6cf14b5d-c8df-a58b-78ea-b2a1ef5701ad.png)

**演出スキップ**と**リザルト終了**の条件は「ユーザーがタップした瞬間」になるので`Trigger`パラメーターで設定します。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/108458/38435b7b-89f4-a7f2-9fd6-b52c43092ca7.png)
`Trigger`パラメーターを設定したら`Has Exit Time`のチェックは外します。
OFFにすると、アニメーションの再生途中でも次のステートに強制遷移させることができます。

その他のスキップや分岐しないものは`Has Exit Time`を**ON　**`Exit Time`は**１**に設定して**「前のステートが１回再生し終わったら次を再生する」**設定にします。
![スクリーンショット 2018-12-19 23.18.52.png](https://qiita-image-store.s3.amazonaws.com/0/108458/158a0765-62a6-9971-8716-74183b8d70c4.png)
`Result_Rank`ステートが通常遷移とスキップ遷移が重なってしまってますがそれぞれ設定できるので大丈夫です。
![04.png](https://qiita-image-store.s3.amazonaws.com/0/108458/3470cb68-c587-deb3-da7b-51f4ab1e9232.png)

最後に`Result_EndIdle`ステートから`Result_FadeOut`ステートに遷移する設定をします。
![05_1.png](https://qiita-image-store.s3.amazonaws.com/0/108458/44b39010-c88b-5014-4f43-eb8dd5ac2af5.png)

`Result_EndIdle`ステートでは**ユーザーのタップ入力を受け付けるまで「タップして終了」を明滅させたい**ので`Result_EndIdle.anim`をループさせます。
![05.png](https://qiita-image-store.s3.amazonaws.com/0/108458/b7637f8d-56a8-a31e-9841-8eba0de08d23.png)

あとはスキップ同様に`Trigger`パラメーターを設定すればOKです！
![06.png](https://qiita-image-store.s3.amazonaws.com/0/108458/95cdfb00-996d-a289-0909-1e31ed15fbe9.png)

**これで分岐の設定ができました！**


##再生して確認する
シーンを再生して一連の流れを確認することができます！
![リザルト1221.gif](https://qiita-image-store.s3.amazonaws.com/0/108458/7384b225-c2bc-f12b-8a29-ef013f4fc52e.gif)

`Hierarchy`タブからアニメーションコントローラーを付けたオブジェクトを選択してみてください。
今再生されているステートがどこなのかコントローラー上で確認することができます！
![遷移.gif](https://qiita-image-store.s3.amazonaws.com/0/108458/82d2dfc2-6e2d-9b66-0ce7-98dadfc00625.gif)
設定した分岐を確認したいときは、`Parameter`タブで設定した`Bool`をON/OFFしたり`Trigger`を引いてみると確認できると思います！
![BoolとTrigger.gif](https://qiita-image-store.s3.amazonaws.com/0/108458/1381f1c5-d204-a6a1-7eb2-b94276b77070.gif)

正しく遷移することが確認できたら、クライアントエンジニアさんに設定した条件とパラメーターの名前を伝えて、プログラムで設定してもらったら完了です！！

##最後に
:raising_hand_tone1:　この方法でやるときは、まずクライアントエンジニアさんによく相談してください
:bow_tone1:　私自身、よくわからないことは省いて説明してます。ごめんなさい

デザイナーがやる必要あるかどうかは分からないですが、分岐を考慮しながらアニメーションを作ることができますし、仕様変更で分岐が変わったときも対応しやすくなるかと思います！

なにより私はゲーム作ってる感があって楽しいのでおすすめです。
パラメーター周りは作ってれば勘でわかると思うのであとはゴリラ力でなんとかなるでしょう！

最後まで読んでくださりありがとうございました！

明日はよもぎさんの「( ᐛ )デザイナー問題ゴリラ的解決法」です。