テラシュールブログ

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

【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

【Unity】Cubeを跳ねさせる

f:id:tsubaki_t1:20170731002426g:plain

今回は小ネタというか、やってみたと言うか…豆腐を跳ねさせるという内容です。

Cubeだって跳ねる

ゲームの仮素材ランキングがあるとしたら、多分ブッチギリで人気No1はCubeでしょう。かのスプラトゥーンですらプロトタイプはCubeだったと聞きます。

つまりCubeには無限の可能性があります。ならば、Cubeは跳ねる事が可能なハズです。

とりあえず、跳ぶ!

とりあえずアニメーションでCubeを跳ねさせてみます。

初期値点から一定時間で最高高度へ、そして一定時間で初期値点へ。リニアな移動です。

f:id:tsubaki_t1:20170731002835g:plain

f:id:tsubaki_t1:20170731002922j:plain

か、硬い…!

跳ねてると言うより、上から吊るして持ち上げてると言った方がシックリくるレベルの動きです。

カーブを付ける

跳ねる動きを考えてみます。

基本的にジャンプする瞬間は最高速度で上へ移動し、段々と重力に引かれて減速、最終的に初期加速より重力が勝って落下を開始して、最後に着地…という流れです。

f:id:tsubaki_t1:20170731003448j:plain

f:id:tsubaki_t1:20170731004256g:plain

f:id:tsubaki_t1:20170731004112j:plain

大分ジャンプしてる感が出てきました。

通常のキャラクターならこれでも十分なのですが、Cubeでジャンプだとまだ十分ではありません。なぜならCubeにはモーションが無いからです。

豆腐はフルフルする

Cubeにモーションを設定してみます。

しかしCubeには関節はありません。ならばどうするか…Scaleを使います。

Cubeのような物がジャンプするには、どんなモーションが必要か。

  • 平べったくなり力を溜める
  • 反動で上に跳ねる(縦に伸びる)
  • 縦に伸びた反動でフルフルする
  • 落下開始
  • 地面に着地した衝撃でぺたんこになる

f:id:tsubaki_t1:20170731004828j:plain

f:id:tsubaki_t1:20170731004842j:plain

これで跳ねます。
単純なScaleですが、タイミングを調整することで何というか見ていて気持ちのよい感じの動きになったんじゃないかなと思います。

f:id:tsubaki_t1:20170731005119g:plain

頂点単位でモーフしたい?うるせぇ豆腐ぶつけんぞ

 

という事で、異世界転生したらCubeだって勇者を目指せる話でした。

…言語チート欲しい。英語に対応してるやつ

関連

www.youtube.com