テラシュールブログ

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

【Unity】シェーダーで3Dモデルのアニメーションを行う Animation Texture Baker

f:id:tsubaki_t1:20170903220052g:plain

今回はシェーダーで3Dモデルのアニメーションを行います。

シェーダーで3Dモデルのアニメーションを行う

最近流行りのアプローチの一つに、シェーダーでモデルのアニメーションを行う…という物があります。

例えば各頂点のXYZ等の情報をテクスチャのRGBAに格納し、それの読み取り位置を時間でズラす事により、キャラクターのアニメーションを実現する…的な感じです。

f:id:tsubaki_t1:20170903221135j:plain

 

この辺りはUnite 2017のインスタンシング公演で少し触れた他、最近のUniteでは割と何度も取り上げられている項目だと記憶しています。

www.slideshare.net

とりあえずやってみる

作ってみようと思いましたが、既に良い感じのがあったのでソレを使います。

github.com

Animation Texture Bakerの導入

Animation Texture Bakerを導入します。

詳しく確認していませんが、AnimationBakerがあれば多分OKです。

f:id:tsubaki_t1:20170903222051j:plain

テクスチャでアニメーションするモデルの導入

次にモデルとアニメーションを入れます。

この機能はスライドや動画で思想を把握する限り、頂点数やアニメーションの長さに限界があります。また、メッシュは出来れば単一であることが望ましいです。

また Animation Texture Bakerの制限で、Animation(レガシー)のものしか使用できません。

 

ので、それを実現出来るモデルを引っ張ってきます。

例えば http://u3d.as/9WKとか

f:id:tsubaki_t1:20170903221528j:plain

インポートしたアニメーションのタイプはLegacyに設定します。

f:id:tsubaki_t1:20170903222130j:plain

アニメーションの変換

シーンにAnimation付きのモデルを配置し、Animation Texture Bakerをセット、

再生ボタンを押してゲームを再生します。

f:id:tsubaki_t1:20170903222336j:plain

これでBaked Animation Texフォルダに、シェーダーでアニメーションを行うPrefabが生成されます。

このPrefabをシーンに配置すれば、CPUに頼らずアニメーションしてくれます。

f:id:tsubaki_t1:20170903222557j:plain

f:id:tsubaki_t1:20170903223511j:plain

アニメーションをループさせたいならばマテリアルのLoopにチェックを入れたり、時間をズラシたいならDelta Time、速度を変更したいならAnimation Lengthの値を少しいじればOKです。

f:id:tsubaki_t1:20170903222736j:plain

GPU Instancingに対応してみる

初期状態はGPU Instancingには対応していないので、Instancingに対応的な事を軽くしてみます。

Shaderに#pragma multi_compile_instancingとか UNITY_VERTEX_INPUT_INSTANCE_IDとか、UNITY_SETUP_INSTANCE_ID(v);を追加して、物によってはUNITY_INSTANCING_CBUFFER_STARTとかも追加、

f:id:tsubaki_t1:20170903223858j:plain

f:id:tsubaki_t1:20170903225018j:plain

後はGraphics.DrawMeshInstancedで描画します。

これで1023体のゾンビを描画しても、殆どCPU負荷無く描画できています。

Unityが動作する最近のモバイル(MetalやOpenGLES3やVulkan)はインスタンシングが使えるので、割と動きます。*1

f:id:tsubaki_t1:20170903224959j:plain

 Graphics.DrawMeshInstancedIndirectで座標計算をCompute Shaderにやらせれば、CPU負荷は殆ど消せるかもしれません。対応面倒なんでやってませんが。

関連

 

www.youtube.com

 

 
 

*1:現在のAndroidの最低バージョンは4.1なので、OpenGLES3はそこそこ動きます。4.3未満が切れれば…

【Unity】Animator Parameterというウィンドウ

f:id:tsubaki_t1:20170829214417j:plain

何の役に立つのかよく分からんシリーズ

 

紹介する為に色々調べてみたけど、結局用途や使い道がよく分からん…という事でお蔵入りしてた項目も少しずつ紹介していこうと思います。

Animator Parameterというウィンドウ

Animatorの項目にAnimator Parameterというウィンドウがひっそりと存在しています。

これは端的に言えばAnimatorのパラメータを映すだけのウィンドウです。

f:id:tsubaki_t1:20170829214853j:plain

用途は簡単、そうAnimatorのパラメータを映すだけのウィンドウなので、Animatorのパラメータを映す事が出来ます。

f:id:tsubaki_t1:20170829214949j:plain

Animator Parameterウィンドウは何の役に立つのか

役に立つ…といえば、Animatorのパラメータを映す事が…ry

は置いといて、実際問題はどうなんでしょう。

 

Animatorで十分じゃね?

まずパラメータを表示する…という機能においては、Animatorウィンドウで十分です。この項目を独立させる必要性はありません。

Animatorはウィンドウを割と潰せるので、スペースが云々という言い訳も無用です。

f:id:tsubaki_t1:20170829215309j:plain

そうだ、Animatorを観測するのに使えるんじゃね…ん?ロックは何処だ?

ではロックすればどうでしょう。Animator Parameterが各Animatorのパラメータのみを表示し、状況を把握するのに役に立ちそうです。

 

さて、ロックは何処でしょう?

f:id:tsubaki_t1:20170829215613j:plain

答えは「無い」です。

 

Animator Parameterの表示する項目は常にAnimatorウィンドウと同じ内容を表示します。例えAnimatorをロックしたとしても、同じ内容です。

ソレ以前にAnimator Parameterはウィンドウを一つしか用意出来ないので、Animator Parameterを複数使ってパラメータを観測…みたいな事は出来ません。

 

強いて言うなら…

Animatorのウィンドウを別ディスプレイに表示して、パラメータだけを観測したいとか、そういった用途でしょうか…?うーん。

 

で、Animator Parameterはどうやって活用するの?

あ…AnimatorのParameterを見るのに使えるヨ…

 

感想

理解出来ると化ける機能もあるけど、

…用途不明な機能は意外と多い

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

【Unity】Polygon Collier 2Dの頂点を調整する

f:id:tsubaki_t1:20170822233336j:plain

今回は2DのPolygon Collier 2Dの頂点を調整する方法についてです。左の絵が右のようにスッキリします。

Polygon Collier 2Dの頂点は解像度で決まる

コライダーを計算する際、頂点数が多いよりは小さい方が負荷は低めです。とは言え、綺麗にくり抜いた方が理不尽な当たり判定にならない傾向にあります。

パフォーマンス的にはBoxやCircleを組み合わせた判定を用意するのが良いのですが、所詮は組み合わせ、綺麗に組むためには手間が必要です。

f:id:tsubaki_t1:20170822235202j:plain

 

その辺りPolygon Collier 2Dを使用すると、スプライトのアルファでコライダーの形状を設定してくれるので、地形やスプライトに沿った当たり判定が割と楽に実現出来ます。

キャラクターの頭のような構造も一発です。

f:id:tsubaki_t1:20170822234255g:plain

 

このPolygon Collideが使用する超点数ですが、どうやら画像の解像度で頂点の細かさを決定しているみたいです。

下の絵は2048、256、64の解像度の立ち絵を同じスケールにしたものです。小さい解像度の絵は判定が荒く、大きい解像度の絵は判定が細かくなっている事が確認出来ます。

f:id:tsubaki_t1:20170822234602j:plain

判定を調整したくなるケース

高解像度で(ズームに耐える)絵は細かい判定も綺麗に耐える、粗い(小さい)キャラクターは大雑把…まぁそれは楽なのですが、これが微妙なケースもあります。

 

例えばドット絵は確実に解像度が低いですが、判定が雑であっては困るかもしれません。また、高解像度であっても、判定が雑で良いケースもあるかもしれません。

f:id:tsubaki_t1:20170822235745j:plain

f:id:tsubaki_t1:20170822235922j:plain

コライダーを調整する

コライダーを調整する場合、現状二種類の方法があります。

一つ目はPolygon Collier 2DのEditを使用する方法、もう一つはEdit Physics Shapeで調整する方法です。

Polygon Collier 2DのEdit Collier

Polygon Collier 2DのEdit Collier を押すと、コライダーの計上をシーン上で微調整出来ます。

頂点の位置を調整したり、頂点を増やしたり、Ctrlを押しながら頂点を削除したりと、まぁ簡単な調整はコレでも可能です。

f:id:tsubaki_t1:20170823000329g:plain

ただ、この情報は編集したPolygon Collier 2Dに格納されるので、同じようにスプライトを配置してPolygon Collier 2Dを追加すると、編集前のPolygon Collier 2Dが追加されます。

 

Tips:Polygon Collier 2Dをリセットするとコライダーが元に戻ります。

またPolygon Collier 2Dのコンポーネント内容をコピーすれば、コライダーの内容が移植されます。

f:id:tsubaki_t1:20170823001027g:plain

 

ちなみに、単純に穴を塞ぎたい場合はPointsのPathsを減らすと良いです。

f:id:tsubaki_t1:20170823003121j:plain

Edit Physics Shape

Edit Physics Shapeは最近追加された機能で、スプライトの初期設定のコライダーを調整します。
専用ビューなので、Edit Collier のように選択ミスでフォーカスが外れたりしないのが非常に助かります。あと複数選択

f:id:tsubaki_t1:20170823001527j:plain

Edit Physics ShapeはSprite Editorから入ります。その後、SpriteEditorでEdit Sprite Shapeを選択すればコライダーの編集画面になります。

f:id:tsubaki_t1:20170823001357j:plain

 

初期設定のコライダーの細かさをOutline Toleranceで調整したり、コライダーの形状を調整したり出来ます。

f:id:tsubaki_t1:20170823001910j:plain

f:id:tsubaki_t1:20170823002310g:plain

ちなみに、頂点が3つ以下になるとコライダーの形状がリセットされるという謎挙動です。形状をイチから作りたい場合は、全消しではなく半殺しにしてボコボコにする感じで。

関連

tsubakit1.hateblo.jp

【Unity】Prefabの”モデルの差し替え”を、セットしたコンポーネントを一々付け直さずに行う方法

f:id:tsubaki_t1:20170819214225j:plain

今回はModelの更新に関するTipsです。

モデルの差し替えのトラブル

ゲーム開発を進める時、最初からモデルはFix済みの物を使う訳ではありません。例えばボーン構造が変化したり、メッシュの中身が変化するといった事は良くある事です。

この時、Animator以下のオブジェクトにコンポーネントをセットしていなければAnimator以下のオブジェクトを差し替えるだけで済みます。
メッシュの頂点やUV変更等であれば、ファイルの上書きで更新するならばオブジェクトの差し替えも要らないかもしれません。

f:id:tsubaki_t1:20170819215432j:plain

逆に、Animator以下のオブジェクトにコンポーネントをセットしている場合…例えばRagDollをセットしているような状況だと、面倒なことになるかもしれません。

単純にMeshの差し替えでは上手く動作しなかったり、旧Prefabと新Prefabを比較して何が接続されているのかを確認したり。

オブジェクト構造やコンポーネントを維持しつつモデルを差し替え

モデル調整の度にコンポーネント構造を再セットするのは面倒なので、コンポーネントの情報を維持しつつモデルを差し替えるアプローチです。

これはOtimize Transform Hierarchyがコンポーネントがアタッチされているオブジェクトを破棄せず、かつDeoptimize Transofrm Hierarchyで巻き戻した際にAvater情報を元に再構築する…という流れを利用しています。

 

大雑把な流れとしては、

  1. オリジナルのPrefabでOptimize Transform Hierarchyを実行
  2. PrefabにセットされているSkinedMeshRendererを削除
  3. 移植したいモデルをシーンに配置し、Optimize Transform Hierarchy
  4. 新しいモデルのSkinedMeshRendererをオリジナルPrefabに移植
  5. オリジナルPrefabのAvaterを、新しいモデルの物に変更
  6. オリジナルPrefabでDeoptimize Transform Hierarchyを実行

といった流れです。

実際の流れ

最初はこの状態からスタートです。

f:id:tsubaki_t1:20170819224826g:plain

AnimatorをOptimize Transform HierarchyでHierarchy構造をスッキリさせます。これでボーン構造が実際のGameObjectに左右されなくなります。

この時、コンポーネントがセットされているオブジェクトは非表示にならず残ります。

f:id:tsubaki_t1:20170819222451j:plain

f:id:tsubaki_t1:20170819222823j:plain

次に、オブジェクト以下のMeshRendererやSkinedMeshRendererを削除します。

これは、単純にMeshがMissingになってしまったり、旧モデルを維持しつつ新モデルをセットしたい場合の手順です。

探すのが面倒ならば、Hierarchyの検索機能でRenderer系だけ探して消します。

f:id:tsubaki_t1:20170819224022j:plain

移植したいモデルもシーンに配置し、Optimize Transform Hierarchyを実行します。その後、移植したいモデルのRenderer系を全てPrefab以下に移動します。

f:id:tsubaki_t1:20170819224438j:plain

後はPrefabのAvaterを更新し、Deoptimize Transform Hierarchyを実行します。

Avaterの情報を元にTransformの構造を直すっぽいので、この順番を間違えると正常に動作しないかもしれません。

f:id:tsubaki_t1:20170819224746j:plain

これで完了です。

f:id:tsubaki_t1:20170819225126g:plain

全体の作業Gifはこんな感じです。

f:id:tsubaki_t1:20170819224856g:plain

コンポーネントの参照先は残らない問題

このアプローチでは、コンポーネントの参照先は消えてしまうかもしれません。Optimize Transform Hierarhyはコンポーネントが付いている物は残しますが、他のコンポーネントが参照しているものまでは判定していないみたいです。

参照先にコンポーネントがあれば問題無いですが、Transformのみのコンポーネントを参照している場合は注意が必要です。

f:id:tsubaki_t1:20170819231128j:plain

この辺りでも、コンポーネントが直接参照するよりコンポーネントが自己登録しに行くアプローチの方が安定するかもしれません。直接参照の方が早くはあるんですけどね…

f:id:tsubaki_t1:20170819231139j:plain

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

madnesslabo.net