今回はTimelineで物理演算のような動きを再現するアプローチについてです。
物理表現的な動きをTimelineで使いたい
Timelineで簡単な動画を作成していると、物理表現的な表現を使用したくなるケースが多々存在します。
例えば玉が跳ねるであったり、扉が壊れるであったり、揺れモノであったり。
そういった表現を作る場合はアニメーションでカーブを作る必要があるのですが、コレが結構面倒くさいです。
本当にごく単純なアニメーションなら楽で良いのですが、少しでも複雑になると手間が大幅に増える他、簡単に不自然な動きになります。
ではTimelineでの制御を止めてコンポーネント単位で動かそうとなる訳ですが、3つ問題があります。
1つ目は物理演算は毎回確実に同じ動きをする訳ではないという点です。端末のCPUやFPS遅延の有無によって多少結果が変動します。
またTimelineでのプレビューが出来ない点も問題です。もし物理演算的に動くナニカが演出の重要な項目を担っている場合、その動きと演出のタイミングを合わせるのは至難の業です。
パフォーマンス的な点もあります。位置情報を読み取るだけのアニメーションと比較して、物理演算は多くの計算を必要とします。その物理演算で動かす対象の量がとても多かった場合、その演出には非常に高い負荷が発生してしまいますし、事前に用意するコストも地味に大きいです。
物理演算の動きをAnimationClipに変換してしまおう
そこで思いつくのが、物理演算的な動きをAnimationClipに変換してしまおうというアイディアです。
AnimationClipに変換することで幾つか出来ることがあります。
- 物理演算の「動き」のみを再現出来る
- RigidbodyやColliderは不要
- Timelineでプレビュー出来る
- 量によるが普通に物理演算するより軽い
勿論、物理演算のようなインタラクティブな反応を返す事は出来ませんし、物理演算の結果「期待したような動きにする」事は難しいかもしれませんが、やって見る価値はありそうです。
GameObjectの動きをレコードする
AnimationClipに変換するため、GameObjectの動きをレコードします。
これはGameObjectRecorderというAPIがあるのですが、AssetStoreにあるRecorderでも対応する機能があるので、今回はそちらを使用します。
まず最初にTimelineで動かしたいオブジェクトを用意します。
このオブジェクトは親オブジェクトを用意しておくと、あとで色々と楽です。
なお、子オブジェクトは全てユニークな名前を指定する必要があります。オブジェクトのバインドは名前単位で行うので、同じ名前は使えません。
逆を言えば、オブジェクトを差し替えるときに名前さえ一致してれば何とかなるという話でもあります。
次にTools > Recorder > AnimationClipsでウィンドウを開き、
GameObjectに先程用意した親オブジェクトを登録します。
複数のオブジェクトを登録したい場合はAdd Object To Recordでレコードしたいオブジェクトを増やします。
また、Transform以外もレコードしたい場合はRecordedTargetsで複数選択します。
なお、ココで指定できるのは「子オブジェクトも含めた全てのコンポーネント」です。
あとはStart Recordingボタンを押せばレコードが開始され、Stop RecordingでAnimationClipがプロジェクトに生成されます。
動きに問題が無さそうなら次のステップです。
Timelineに使用する
次にTimelineにバインドします。
手順は単純で、Recorderで保存したオブジェクトをTimelineに登録するだけです。
Rigidbodyとか、その辺りを全て外す
Timelineで動くのが確認出来たら、最後にRigidbodyやColliderも外してしまってOKになります。
完全にTimelineで動くオブジェクトに物理演算の動作は不要なので外してしまいます。
もしくはIsKinematic。
これは動かすオブジェクトの量が多い場合、パフォーマンスを劇的に改善します。
注意
Humanoidに使用する場合
このアプローチ、少し考えればラグドールに使ってしまおうと考えるかもしれません。
物理演算を使用せず単純なアニメーションでキャラクターの転倒を再現するのは非常に低負荷であり、地形に沿ってキャラクターが倒れる必要がない場合は、それはたしかに有効そうな手に見えます。
下はラグドールをアニメーションに変換して再生したもの
例えば120体のラグドールを全てAnimationClipでキャプチャして直した場合、ラグドール(右)が5~10msかかったのに対し、アニメーション(左)の場合は概ね0.5ms以下に収まっています。
ただ注意すべき点として、このアプローチで取得できるキャラクターのアニメーションはGenericタイプであるという点があります。そのためキャラクターのリグがHumanoidの場合は互換性がありません。
また常に同じ動きをしてしまう関係上、死屍累々感はありません。
まぁ、ここまで規則正しく並べなければそうでもないとは思いますが…
キーフレームの数が結構凄いことになる
もう一つの問題は、キーフレームの数が結構エグい事になる点です。
Unityのリダクション機能も使えないですし、カーブで補完してくれる感じではないので、ちょっと注意が必要かもしれません。
初期設定では60FPSでレコードするので、30FPS辺りにすると結構良い感じに減りそうです。
感想
作るのが面倒だった(上手くリアルな感じで作れなかった)物理演算的な動きを、手抜きして作る方法についてでした。
関連
全てのオブジェクトを物理演算で動かす→最低10FPS、オブジェクトをGameObjectRecorderでClipに変換してTImelineで動かす→最低80FPS #unity pic.twitter.com/IcGqK0mcTP
— 椿 (@tsubaki_t1) May 4, 2018
Timelineのプレビューのみで物理演算を再生するアプローチです。
求める結果を得るために試行錯誤する場合に使えます。
画面を録画出来るRecorderです。かなり便利