今回はUnity 2017.1で正式導入となったPlayable APIについてです。
PlayableAPIはAnimatorのLowLevel API(のようなもの)
まずPlayable APIとは何ぞやという話ですが、大雑把に言えばAnimationを再生する為の物です。
何が便利かと言えば、AnimationControllerを量産する事無くアニメーションを再生、動的なアニメーションの追加、そしてアニメーション同士をブレンドする事が期待出来ます。
AnimationControllerは、どちらかと言えば全パターンを網羅した物を用意して「すべてを埋めない」に対して、Playable APIは逐次PlayableGraphに追加していくイメージです。
ちなみに、この技術はAnimatorだけでなくTimelineにも使用されており、オーディオやスクリプト制御にも応用が効く機能ではあります。
…パーティクルも一緒に制御してくれても良いのよ?
なお、Playable APIは余りセーフなAPIでは無いようで、開放忘れ等で簡単にUnityエディターをクラッシュさせます。Threadやstaticと同じように、十分に注意する必要がありそうです。
アニメーションのブレンド結果をOutputに出力する
Playable APIを説明する場合、大きく分けて3つの要素があります。
Playable Graph、PlayableOutput、そしてPlayableです。
Playableは、アニメーション再生やオーディオ再生を制御するためのコマンドです。ココでどのアニメーションを再生するのか、どういったブレンドを行うのかを制御します。
Playableの結果を出力する先はPlayable Ouputです。Ouputに出力された結果はバインドしたAnimatorに流し込まれます。
Playable Graphは複数のPlayableやOutputを持つグラフです。
要するにoutputに何を流し込むかで、再生するアニメーションが変わります。
AnimatorをPlayable API的に見てみる
Playable APIはスクリプトで基本的に作成します。その際、どういった形でグラフが構築されているのかをPlayableGraph Visualizerで確認する事が出来ます。
これでAnimatorを見てみると、下のようなグラフになります。
AnimationControllerでどのステートで再生するのかを決定、Layerでレイヤー単位のアニメーション加算・上書き合成を制御します。
面白いのが二つのAnimationMixerで、アニメーション切替のタイミングで下に以前再生していたAnimationClip、上に次に再生するAnimationClipを流し込み、アニメーションのブレンドを実現しています。
Playable APIを実際に使ってみる
それでは実際にPlayable APIを使用してみます。
なお、日本語マニュアル(Unity 5.4)のサンプルコードは動作しません。最低でもUnity 2017.1のマニュアルが望ましいです
AnimationClipを動的にロードしてアニメーションを再生する
まずはAnimationClipを動的にロードしてアニメーションを再生してみます。
必要な物は5つ。
- UnityEngine.PlayablesとUnityEngine.AnimationsのNamespace、
- PlayableGraphの生成と破棄
- 再生するAnimationを持つAnimationClipPlayable
- 出力先のPlayableOutput
- 流し込む先のAnimatorコンポーネント
これで動的に取得したアニメーションをAnimatorで再生する事が可能です。
複数のアニメーションの切替
アニメーションの切替はAnimationMixerPlayableを使います。
まぁOutputへ流し込むAnimationClipを切り替えても良いのですが、Mixerを使用した方がブレンドが出来て便利です。またAnimatorのInitializeも回避出来ます。
正確には切替というより、複数のAnimationClipPlayableのウェイトを変更する感じです。
複数のレイヤー制御
アニメーションを行う場合、表情や上半身・下半身でのレイヤー制御等を行いたくなる場合があります。そういった場合ではレイヤーの加算合成が使えます。
上手く使えばギミックをPlayableAPIで動かすことが可能です。ただし、編集にはAnimatorが必要なので、若干の片手落ち感はあります。
二つのAnimationClipPlayableを使いまわす
AnimationClipPlayableを全登録せず、随時追加・破棄していくパターンです。
基本的にはAnimationControllerで、必要な時だけAnimationClipを足す
ある程度AnimationControllerで制御したいが、(例えば宝箱をあけたり、畑を収穫したり等の)特殊イベント時に任意のアニメーションを足したい場合のアプローチです。
アニメーション終了後にPlayableを破棄します。
PlayableGraphをAnimatorから持ってくる場合は、AnimationControllerはAnimatorから抜いておく必要があります。
一応、既に再生中に割り込む方法もありましたが、どちらかと言えばAnimationControllerPlayableを使用したほうが安定する印象です。
注意点
- エディターで、ゲーム再生中にフォーカスが外れた状態で放置すると、再開時にアニメーション再生がゆっくりになる(ビルドした物はフォーカスが外れても大丈夫)
- PlayableGraphを開放忘れると落ちる事がある(ので、AwakeとOnDestroyで生成・開放を管理)
- 開放漏れ等は「2回目の再生」で落ちる