非ゲーム分野でUnity Animatorの想定外の挙動を避けるために

この記事は[クラスター Advent Calendar 2020](https://qiita.com/advent-calendar/2020/cluster)の19日目の記事です。

クラスターで3DCGアニメーター/モデラ―っぽいことをしているMSA_iです。３年目にして初アドベントカレンダーです🤣
今回はUnityのAnimatorについて書いていこうと思います！！


#はじめに
UnityのAnimator、便利ですよね

ゲーム等のインタラクティブなコンテンツはもちろん、非インタラクティブなコンテンツ（ライブなど）を制作するときにもTimelineと合わせて活用することが多々あります。
~~ライブだってインタラクティブであるべきだろ～という話はひとまず置いておいて~~
ところが、UnityはGame Engineなので、インタラクティブなコンテンツを制作するための機能に重点が置かれており、非インタラクティブなコンテンツをつくる場合にはこの機能群がかえって邪魔になることがあります。

また、作業者個々人でアニメーションデータの作り方に違いがあったり、Animatorの設定が異なっていたり、Objectの親子関係が異なっていたりしたら作業しづらいですよね。（アニメーションを設定したらモデルが彼方に吹っ飛んでいったとか、ちょっとずつズレていくなんて話を聞くことも…

そこでこの記事では、これらの問題を解決するべく、ベストなAnimator・Timelineの設定やアニメーションオブジェクトの最適な構造を探っていきます。


#結論
いきなり結論です。

1. Rootを配置しよう
2. Apply Root MotionはONにしよう
3. Remove Start OffsetはOFFにしよう

その他の設定に関してはデフォルトのままで問題ないと思います！

では、このような結論になる理由を解説していきます！


#Rootの役目とは何ぞや
いきなりRootの話をします。そもそもRootと聞いてピンとこない方もいるんじゃないでしょうか。
全てのObject（Bone）の大本に一つだけ存在するObject（MMD流に言うなら「すべての親」）が、Root Objectです。以下、これをRootと呼びます。
まず、これがなぜ重要なのかという話をしていこうと思います。

例えばSceneにAnimatorを付けたObjectがひとつあるとしましょう。
Scene
└Object（Animator）
という状態です。これにX0 → X1のアニメーションを付けます。
![Videotogif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174972/cc790e69-8337-aa06-818f-62b5ae3afdb8.gif)
ここまではRootがなくても何の問題もありません。
では、これをたくさん配置したい！ということになったら？
![Videotogif (5).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174972/66a7b20c-6f44-164a-06f6-7dbd6dcf8307.gif)
愚直に複製して配置するとこうなります。
Objectが1か所に集約されてしまいました。これが果たして求めていたものなんでしょうか。
違いますよね。6個配置したからには、6個がその配置した場所で同じアニメーションをして欲しいわけです。
Animatorは、AttachされたObjectのTransformに値を適用するので、X0 → X1というアニメーションがあれば当然すべてがWorld座標のX0に移動してしまいます。

そこで！！
Scene
└Root
　└Object（Animator）
Rootを置いて、RootのTransformを利用して初期位置を変更してみると…
![Videotogif (6).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174972/b41333f4-0d2a-64e2-d222-fd43ea017275.gif)
同じモーションを使いまわしていながら、X方向に+1動かすことができました。

Rootの重要さを理解していただけましたでしょうか。
もちろん今回の様にSphereが移動するだけなら、アニメーションを6つ作って…なんて対応もできなくはないです。しかし、実際にはこれがBoneが100個もあるようなモデルだったりするので、原点だけずらしたアニメーションをたくさん作って...なんてことをしていたら、手間の面でもデータサイズの面でも大問題になるのです。

そして、Rootを使うメリットはもう一つあります。
諸事情によりアニメーションするオブジェクトを突然移動させなければならなくなった場合などに、Unity上でさっと位置合わせをするだけで対応できるのです。
通常、UnityでSceneを作る場合はパーツをDCC（Digital Content Creation）ツールで作成し、それをUnity上で配置していく場合がほとんどです。しかし、モーションもそうして作られたパーツの一つなので、DCCツールで制作されています。つまり、完成したSceneのデータをモーションを編集するDCCツール上で確認しなければ、位置合わせができないのです。Unity上のSceneをエクスポートしてDCCツールで読み込んで、そこからモーションの修正をするというのは非常に手間です。この手間を省けるという意味でもRootは重要なのです。

**気を付けるべきことその1　Rootを配置しよう**

#Apply Root Motion
次は、Apply Root Motionの話をします。
Rootの話はUnity以外のCG分野全般に共通した話でしたが、ここからはUnityの話です。

Animatorには、Apply Root Motionというチェック項目があります。
デフォルトではOFFです。

この機能は、AnimatorがアタッチされたObjectのRootにアニメーションのRootの動きを反映するというオプションになります。
ゲームを制作する際には、アニメーションの影響を受けてキャラクターがあっちこっち動いては作りづらかったりするので、デフォルトではOFFになっています。（アニメーションを差し替えるたびに当たり判定が動いたりしたら発狂する人が現れそうですね

で、これが良くできているというべきかなんというか、ソースファイル（FBX、glTF..）のScene直下のObjectが必ずしもRootとして反映されるわけではありません。（多分、移動量ゼロのObjectは無視される？UnityのImporter側の仕様のような気もします

↓のアニメーションではHipがRootとして認識されているのでこのような動きになってしまいます
![Videotogif (7).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174972/66ab5270-be12-d9bb-d47b-6c4d90abb2c5.gif)

というわけで、作るのがゲームでなければONがおすすめです。
DCCツールで表示されるアニメーションがそのままUnityに反映されないと困りますもんね
![Videotogif (9).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174972/6521cd20-aefe-c809-ccf8-b68549619b98.gif)

**気を付けるべきことその2　Apply Root MotionはONにしよう**

ちなみに、先ほどの球体たちにRootを追加せずにApply Root MotionをONにすると、このような動きになります
![Videotogif (8).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174972/e68c1879-8dbc-1805-a7aa-eea6d536fec2.gif)
一見、良さそうに見えますが、現在の位置にアニメーションの値がどんどん加算されてしまうため、どんどん進んでいってしまいます…

#Remove Start Offset（Timelineのオプションです）
次に、Remove Start Offsetについて話していこうと思います。
これは、Timeline（正確にはAnimation Playable Asset）の機能の一つです。
なんでいきなりTimelineの話になるんだ？と思われるかもしれません。しかし、前述のように、一方向のコンテンツを制作する際にはAnimatorとTimelineを併用する機会が多いので、この機能の解説は外せません。
~~この機能の挙動がわかりにく過ぎるというのもある~~

Remove Start OffsetはデフォルトでONです。
この機能がONになっていると、AnimatorがアタッチされたObjectの位置・方向と、アニメーション内のRootの初期位置・方向が揃います。
つまり、原点から開始されるアニメーションじゃなくても、現在Unity上で配置している位置・方向からアニメーションを開始させられます。

一見便利そうです。

ところが…
もしDCCツールなんかでアニメーションを修正して初期位置が変わろうものなら、さあ大変
「キャラクターが曲の中盤でファンの前に来るようにUnity内で位置を調整していたのに、初期位置が変わった分だけずれて、あらぬ位置であらぬ方向を向いている！」なんてことになりかねません。
アニメーターが一生懸命調整してくれたものですから、Unity内でも位置関係が変わってほしくはありませんよね。
というわけでRemove Start OffsetはOFFがおすすめです。

Remove Start OffsetがOFFであれば、ソースファイル（FBXなどなど）の原点と、Unity内のAnimatorがアタッチされたObjectの位置・向きが同一になる、と言った方がわかりやすいかもしれません。

**気を付けるべきことその3　Remove Start OffsetはOFFにしよう**

#Update Mode
物理シミュレーション系のBoneが荒れ狂うときなどはAnimate Physicsにしてみると直るかもしれませんが、基本的にはデフォルトのNormalで問題ないです。

#Culling Mode
Always Animateが無難だと思います。負荷が気になるようであればCullにするのも一考ですが、Root Motionを利用していると画面外に出た結果、アニメーションの再生が止まり、想定外の動きになることがあります。

#Foot IK（Timelineのオプションです）
デフォルトではONで、そのモデル（Humanoid）専用アニメーションでなくても、脚部の長さの違いをそこそこ吸収してくれます。
しかし、Foot IKのターゲットのないAnimファイルを作ることができるようで
その場合、この機能をONにしていると足が吹っ飛びます。
ただ、そのモデル専用のアニメーションであればOFFでも問題ないでしょう。

#最後の結論
Unity偉い
オプションをカチカチいじるだけで求めている挙動になる！Unity凄いですね🤗
次回はkyokomiさんの「Androidについての何か」です！