テラシュールブログ

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

【Unity】動作が完結してるアニメーションを分割する

例えばジャンプアニメーション等、AssetStoreから入手したアセットのアニメーションが繋がっている事があります。

そういった時に、アニメーションを分割するアプローチについてです。

繋がっているアニメーション

ジャンプ等のアニメーションは、繋がっていない場合と繋がっている場合があります。これは単純に用途の問題で、

  • 繋がっている場合:MatchTarget等で段差を飛び越える等の、固定で動く移動
  • 分かれている場合:ジャンプモーション等に使用する

といった感じでしょう。

f:id:tsubaki_t1:20170807233650g:plain

固定移動の場合は繋がっている方が、シーケンスの制御が楽で良いのですが、ジャンプ中といった場合はそうはなりません。
オブジェクトの晒されている状況に応じて適当なアニメーションを割り当てる必要があります。
例えばジャンプアニメーションの流れは下のようなモノになると思いますが、

  1. ジャンプ開始
  2. ジャンプ上昇中
  3. ジャンプ中
  4. ジャンプ下降中
  5. 着地

アクションゲームではジャンプ開始は固定でも、ジャンプ上昇時間やジャンプ下降時間は可変である事が予想されます。

アニメーションを分割する

繋がっているアニメーションで可変するアニメーションを表現するのは面倒です。なので、単純にアニメーションを複数のAnimationClipに分割し、Mecanimのステートで制御可能にしてしまいます。

 

分割…と書きましたが、アニメーションを分割して3つのアニメーションにする等では無く、短いアニメーションを作るといった流れが正しいです。

作業の流れ

Modelを選択してAnimationImporterを開きます。

f:id:tsubaki_t1:20170807234836j:plain

後は+を押して新しいAnimationClipを生成、範囲を絞ってアニメーションの一部を取り出します。例えばJamping@loopは170.0~238.0の間のアニメーションなので、そこからジャンプ開始・ジャンプ上昇中・ジャンプ中・ジャンプ下降中・着地を取り出す訳です。

f:id:tsubaki_t1:20170807234648j:plain

f:id:tsubaki_t1:20170807235031g:plain

docs.unity3d.com

関連

tsubakit1.hateblo.jp

【Unity】PrefabにScriptableObjectを格納する

f:id:tsubaki_t1:20170803233437j:plain

今回はPrefabにScriptableObjectを格納する話です。

ScriptableObjectを使うと何が良いの?

Prefabをインスタンス化する場合、コンポーネントの複製が行われます。もしインスタンス化したPrefabのパラメータが殆ど変更無い場合は、これは非常に無駄になります。

例えばEnemyというPrefabを作成し、EnemyStateコンポーネントには以下のようなデータが大量にあったとします。

  • 敵の名前
  • パラメータ
  • スキル一覧
  • アニメーション一覧

そういった場合、オブジェクトをインスタンス化する度に、コンポーネントはこれらのパラメータを格納するメモリを要求します。また、パラメータの流し込みコスト(地味に重い)が発生します。
あと開放コストも地味に増えます。DestroyやUnloadが妙に重い場合は、単純に数が多すぎたり、パラメータが多すぎたりするのを直すと、治ったりします。

f:id:tsubaki_t1:20170803235036j:plain

コレを回避する最も手っ取り早い方法がScriptableObjectにパラメータを退避する事です。Prefabは一つのScriptableObjectを参照し、Prefabからインスタンス化したオブジェクトは一つのScriptableObjectを参照する。
これならばロードコストもパラメータのメモリ消費も1回で済みます。

f:id:tsubaki_t1:20170804000226j:plain

ただ、ScriptableObjectを生成するとプロジェクトが散らかります。1Prefab 1ScriptableObjectと考えても、Prefabが100体になると管理が煩雑になる事が予想されます。

f:id:tsubaki_t1:20170804000110j:plain

SriptableObjectをPrefabに格納してしまおう

指定Prefabしか使わないのに別にScriptableObjectを用意すると色々と管理が面倒そうなので、Prefab内にScriptableObjectを格納してしまいます。

こんな感じに。

f:id:tsubaki_t1:20170804000930j:plain

f:id:tsubaki_t1:20170804083402j:plain

サンプル

サンプルコードでは、PrefabのコンテキストメニューからAddを足すとScriptableObjectが追加され、Removeすると破棄されます。

このPrefabから生成したインスタンスは全てPrefabに格納したScriptableObjectを参照している感じです。

f:id:tsubaki_t1:20170804001523g:plain

gist.github.com

 

f:id:tsubaki_t1:20170804000433j:plain

Tips

  • Prefabかどうかの判定は、 PrefabUtility.GetPrefabTypeが楽です。
  • Prefab内のオブジェクトを取り出すのはAssetDatabase.LoadAllAssetsAtPathです。
  • Prefabの中に格納したScriptableObjectのOnEnableはPrefabを参照していると自動で呼ばれます。

【Unity】AnimationControllerを用意せずAnimatorによるアニメーションを使う

f:id:tsubaki_t1:20170802223713g:plain

Playable APIを使用してアニメーションをAnimationController無しで制御します。

大量のアニメーションとAnimationController

Animation Controllerは、キャラクターのアニメーション制御を行う上で便利な機能です。上手く作れば、キャラクターの状況を流し込むとキャラクターが現在取るべきアニメーションを取ってくれる…といった事が期待出来ます。

http://cdn-ak.f.st-hatena.com/images/fotolife/t/tsubaki_t1/20151221/20151221025751.jpg

 

とは言え、上手く使いこなせないと面倒なシステムでもあります。所謂ステートマシンのスパゲティ状態や、大半のアニメーションが単一のステートを指すような状態になると、非常に管理が煩雑な状態になるかもしれません。

また大量のAnimation Controllerがプロジェクト内に氾濫するといった事も起こります。

http://cdn-ak.f.st-hatena.com/images/fotolife/t/tsubaki_t1/20151220/20151220110821.jpg

 

これについて、以前AnimationControllerを散らさないアプローチについての記事を書きましたが、Unity 2017.1よりPlayable APIがちゃんと使い物になったので、不要になりそうです。

tsubakit1.hateblo.j

Playable APIとは何ぞや

Playable APIについてはコチラ

tsubakit1.hateblo.jp

Playable APIでAnimationっぽい事をしたい

Playable APIでAnimationっぽい事をします。

完全にAPIを模倣するというよりは、AnimationController無しにAnimationClipやAnimation Nameを指定したら再生するといった事を実現する事が目標です。

上手く行けば、本記事トップのGifアニメのようなボタンを押したらアニメーションを再生する的な事が実現出来ます。

ソースコード

コードはこんな感じです。

gist.github.com

Cross Fadeでアニメーションをフェードしながら切り替えます。アニメーション名を指定する場合は事前にClip Listに登録が必要です。AnimationClipを直指定する場合はClipListに登録する必要はありません。

Playはアニメーションをフェードせず切り替えます。主に2D用です。

  • CrossFade (AnimationClip clip);
  • CrossFade (string animation);
  • Play (AnimationClip clip);
  • Play (string animation);

なお、ClipListには最低一つのAnimationClipの登録が必要です。

f:id:tsubaki_t1:20170802225713j:plain

サンプル

使い方です。

f:id:tsubaki_t1:20170803115442g:plain

まずAnimatorの設定されてるモデルと同じGameObjectにSimple Animatorを登録します。その際、AnimatorのAnimation Controllerは必ずNoneにします。

AvaterやUpdate Mode、Culling ModeはAnimatorのパラメータが使われます。必要に応じて設定します。

f:id:tsubaki_t1:20170802225935j:plain

 

Clip Listに最低一つのAnimationClipを登録します。
AnimationClip名で再生するアニメーションを切り替えたい場合は、切り替えたいAnimationClipを全て登録します。

f:id:tsubaki_t1:20170802230202j:plain

 

後はSimpleAnimator.CrossFade( "animationclip名"); 等を実行すれば、アニメーションを再生してくれます。これはAnimationClip名ですが、AnimationClip直再生でもOKです(その場合はClipListに足す必要はありません)

gist.github.com

また、EventSystemからも呼べます。
ボタンを押したらアニメーションとかは、コレが楽かもしれません。

f:id:tsubaki_t1:20170802235356j:plain

 

問題

  • アニメーションの編集には使えません。
  • Playable APIの問題を引き継ぎます

関連

AnimationControllerも使いたい人向け

tsubakit1.hateblo.jp

【Unity】「PlayMakerによる初めてのUnityプログラミング」

f:id:tsubaki_t1:20170801230425j:plain

Playmakerに関する良い感じの資料が公開されたのでメモします。

Playmaker…一体何藤木遊作なんだ…

PlayMakerによる初めてのUnityプログラミング

件の資料はコチラ

www.slideshare.net

Playmakerの紹介からRoll a Ballを作成するワークショップまで

内容は先日のUnity道場PlayMakerによる初めてのUnityプログラミングの内容で、

  • Playmakerの紹介
  • Playmakerのインストール
  • 基本的な操作方法

から始まり、最終的には

といった内容みたいです。

www.youtube.com

実際のチュートリアルを操作後、このドキュメントを進めれば差分的な感じでPlayMakerがどういった物か分かりそうです。

関連

unity3d.com