テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】アニメーション制御に色々と良さそうな"Playable API"について云々

今回はUnity 2017.1で正式導入となったPlayable APIについてです。

PlayableAPIはAnimatorのLowLevel API(のようなもの)

まずPlayable APIとは何ぞやという話ですが、大雑把に言えばAnimationを再生する為の物です。

何が便利かと言えば、AnimationControllerを量産する事無くアニメーションを再生動的なアニメーションの追加、そしてアニメーション同士をブレンドする事が期待出来ます。

 

AnimationControllerは、どちらかと言えば全パターンを網羅した物を用意して「すべてを埋めない」に対して、Playable APIは逐次PlayableGraphに追加していくイメージです。

https://cdn-ak.f.st-hatena.com/images/fotolife/t/tsubaki_t1/20160615/20160615234430.gif

ちなみに、この技術はAnimatorだけでなくTimelineにも使用されており、オーディオやスクリプト制御にも応用が効く機能ではあります。
…パーティクルも一緒に制御してくれても良いのよ?

 

なお、Playable APIは余りセーフなAPIでは無いようで、開放忘れ等で簡単にUnityエディターをクラッシュさせます。Threadやstaticと同じように、十分に注意する必要がありそうです。

 アニメーションのブレンド結果をOutputに出力する

Playable APIを説明する場合、大きく分けて3つの要素があります。

Playable GraphPlayableOutput、そしてPlayableです。

 

Playableは、アニメーション再生やオーディオ再生を制御するためのコマンドです。ココでどのアニメーションを再生するのか、どういったブレンドを行うのかを制御します。

Playableの結果を出力する先はPlayable Ouputです。Ouputに出力された結果はバインドしたAnimatorに流し込まれます。

Playable Graphは複数のPlayableやOutputを持つグラフです。

f:id:tsubaki_t1:20170729221944j:plain

要するにoutputに何を流し込むかで、再生するアニメーションが変わります。

AnimatorをPlayable API的に見てみる

Playable APIスクリプトで基本的に作成します。その際、どういった形でグラフが構築されているのかをPlayableGraph Visualizerで確認する事が出来ます。

github.com

これでAnimatorを見てみると、下のようなグラフになります。

f:id:tsubaki_t1:20170729223526j:plain

 AnimationControllerでどのステートで再生するのかを決定、Layerでレイヤー単位のアニメーション加算・上書き合成を制御します。

面白いのが二つのAnimationMixerで、アニメーション切替のタイミングで下に以前再生していたAnimationClip、上に次に再生するAnimationClipを流し込み、アニメーションのブレンドを実現しています。

f:id:tsubaki_t1:20170729223929j:plain

Playable APIを実際に使ってみる

それでは実際にPlayable APIを使用してみます。

なお、日本語マニュアル(Unity 5.4)のサンプルコードは動作しません。最低でもUnity 2017.1のマニュアルが望ましいです

AnimationClipを動的にロードしてアニメーションを再生する

まずはAnimationClipを動的にロードしてアニメーションを再生してみます。

必要な物は5つ。

  • UnityEngine.PlayablesとUnityEngine.AnimationsのNamespace、
  • PlayableGraphの生成と破棄
  • 再生するAnimationを持つAnimationClipPlayable
  • 出力先のPlayableOutput
  • 流し込む先のAnimatorコンポーネント

これで動的に取得したアニメーションをAnimatorで再生する事が可能です。

gist.github.com

f:id:tsubaki_t1:20170729230126g:plain

複数のアニメーションの切替

アニメーションの切替はAnimationMixerPlayableを使います。

まぁOutputへ流し込むAnimationClipを切り替えても良いのですが、Mixerを使用した方がブレンドが出来て便利です。またAnimatorのInitializeも回避出来ます。

gist.github.com

f:id:tsubaki_t1:20170729231923g:plain

正確には切替というより、複数のAnimationClipPlayableのウェイトを変更する感じです。

複数のレイヤー制御

アニメーションを行う場合、表情や上半身・下半身でのレイヤー制御等を行いたくなる場合があります。そういった場合ではレイヤーの加算合成が使えます。

gist.github.com

f:id:tsubaki_t1:20170730004307g:plain

上手く使えばギミックをPlayableAPIで動かすことが可能です。ただし、編集にはAnimatorが必要なので、若干の片手落ち感はあります。

二つのAnimationClipPlayableを使いまわす

AnimationClipPlayableを全登録せず、随時追加・破棄していくパターンです。

gist.github.com

f:id:tsubaki_t1:20170730020401g:plain

基本的にはAnimationControllerで、必要な時だけAnimationClipを足す

ある程度AnimationControllerで制御したいが、(例えば宝箱をあけたり、畑を収穫したり等の)特殊イベント時に任意のアニメーションを足したい場合のアプローチです。

アニメーション終了後にPlayableを破棄します。

gist.github.com

f:id:tsubaki_t1:20170730030538g:plain

PlayableGraphをAnimatorから持ってくる場合は、AnimationControllerはAnimatorから抜いておく必要があります。

 

一応、既に再生中に割り込む方法もありましたが、どちらかと言えばAnimationControllerPlayableを使用したほうが安定する印象です。

tsubakit1.hateblo.jp

注意点

  • エディターで、ゲーム再生中にフォーカスが外れた状態で放置すると、再開時にアニメーション再生がゆっくりになる(ビルドした物はフォーカスが外れても大丈夫)
  •  PlayableGraphを開放忘れると落ちる事がある(ので、AwakeとOnDestroyで生成・開放を管理)
  • 開放漏れ等は「2回目の再生」で落ちる