テラシュールブログ

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

【Unity】背景の多重スクロールをシェーダーで

f:id:tsubaki_t1:20171115235145g:plain

シューティングの臨場感を出すために背景をスクロールする訳ですが、その辺りをシェーダーでやってみました。

1枚の板ポリに複数枚の背景を表示する

まずは下3枚のテクスチャを合成します。

f:id:tsubaki_t1:20171115235559j:plain

下の記事を参考に一枚の板ポリに奥・真ん中・手前の画像を合成するシェーダーを作成してみました。

qiita.com

gist.github.com

作ったシェーダーをマテリアルにセットして、3枚のテクスチャをセットすれば下のような感じになります。

f:id:tsubaki_t1:20171116001135j:plain

f:id:tsubaki_t1:20171115235613j:plain

スクロールさせる

背景をスクロールさせます。

とりあえずノコギリ波で一定時間進んだら戻す感じで。

gist.github.com

f:id:tsubaki_t1:20171116001048g:plain

WebGLでは出来る限りCPUを使いたくないので云々というお話

シェーダーアニメーションのプレビュー

ちなみに、SceneView のAnimated Materialsのチェックを入れると、シェーダーのアニメーションをプレビュー出来ます。

起動直後はチェックが入ってないのにシェーダーが動くという不思議動作もあったりします。

f:id:tsubaki_t1:20171115234911g:plain

【Unity】2DのSprite Animationをプレビューする裏技

f:id:tsubaki_t1:20171114232351g:plain

今回はSprite Animationの内容をプレビューする方法についてです。

悪いな二次太、このアニメーションのプレビューは3D用なんだ

UnityにはAnimationClipをプレビューする機能が備わっています。
それは普通の人形モデルだけでなく、特異なボーン構造を持った動物や昆虫、魚類といったモデルであっても可能です。

f:id:tsubaki_t1:20171114230652g:plain

 

が…2Dは非対応…ッ!

 

2D向けアニメーションをプレビューしようとしても、No Model is avalable for preview(オィイ!プレビュー用のモデルが無いんだが?)の文字が表示され、内容を確認できません。何たる非道。

f:id:tsubaki_t1:20171114230810j:plain

一応Animationウィンドウを開くことで大まかな内容は確認出来るのですが、これでは非常に辛い所です。

f:id:tsubaki_t1:20171114231135j:plain

2Dアニメーションをプレビューする裏技は存在する

さて、2Dプレビューが出来ないせいで今ひとつ内容を把握出来ない訳ですが、一応プレビューする方法はあります。

2Dアニメーションのメッセージ内容に書いてある通り「対応モデルが無くてプレビュー出来ない」ので、対応する物をセットしてやればプレビュー可能になります。

手順はこんな感じ

 

  1. SpriteRendererを持つPrefabを作る
    (Sprite Rendererには適当なスプライトをセットしておく)
  2. 1のPrefabをNo Model is avalable for previewのウィンドウにドラッグ&ドロップする

 

これで2Dアニメーションがプレビュー可能になります。

f:id:tsubaki_t1:20171114232316g:plain

2Dスプライトアニメーションを表示するアセット

ちなみに、2Dスプライトアニメーションを再生するアセットも存在します。

Sprite Animation Previewというアセットで、2Dのスプライトアニメーションを選択した際にプレビューを表示してくれます。

f:id:tsubaki_t1:20171114232603j:plain

こちらのアセットでは選択したスプライトアニメーションを簡単にプレビュー出来る他、複数のスプライトアニメーションを選択した時も同時にプレビューしてくれます。

これには満足さんもニッコリ。

f:id:tsubaki_t1:20171114232851g:plain

 

なお、このスプライトアニメーションは「ユニティちゃんの『コーゲンシティ・オールスターズ!』ユニティちゃんピクセルアートパック for アクションゲーム Vol.2」より

f:id:tsubaki_t1:20171114233126j:plain

 

関連

Simple Animationで2Dアニメーションが色々とやりやすくなりました。

tsubakit1.hateblo.jp

物にも依りますが、量が多い場合はAnimatorよりパーティクルでアニメーションさせた方が4~5桁高速で動作したりします。爆発アニメーションとかにAnimatorは勿体無いかもしれません。

tsubakit1.hateblo.jp

キャラクターとして動かす場合は静的なColliderを動かさないように注意

tsubakit1.hateblo.jp

【Unity】さよならステートマシン。旧AnimationっぽいAPIでアニメーションを再生する SimpleAnimation

f:id:tsubaki_t1:20171114113727j:plain

今回はステートマシンを使用せずAnimatorでアニメーションを再生する、Simple Animationについてです。

ステートマシンにサヨナラを

Unity 4辺りから登場した多機能アニメーション再生機能 Mecanimですが、多くの場合「ステートマシンで制御する」という非常に面倒くさい制御機構を持つせいで、多くの手間がかかってきました。

f:id:tsubaki_t1:20171114114214j:plain

例えばアニメーションにキャンセルが組み込まれると、スパゲティのごとく複雑なステートマシンを(しかもグラフィカルに!)組まなければならず…

例えばアニメーションを動的に追加したいようなケースでは、非常に面倒なお作法が存在し…

例えば普通にステートマシンを管理する場合も、大抵の場合はスクリプト側とステートマシン側で二重にパラメータを管理し…

例えば…例えば…例えば…

tsubakit1.hateblo.jp

そして最終的には多くのプロジェクトで、ステートマシンで管理せずアニメーションクリップ一覧だけ持ってFadeでジャンプするという。

f:id:tsubaki_t1:20171114113806j:plain

という感じで、制御機構に重大な問題を持っていたMecanimサンよりも、問題はあるにしても制御が簡単なレガシーAnimationコンポーネントを未だに採用している人はかなり多かった訳です。

Playable API

色々面倒くさいMecanimでしたが、Playable APIにてアニメーション再生の為の低レベルAPIにアクセスが可能になり、それを単品で処理する事が可能になりました。

tsubakit1.hateblo.jp

これでアニメーションコントローラーを使用せずアニメーションを単体で再生可能になった訳です。

自分もそれを色々とコネコネして、Animation Controllerを使用せずアニメーションを再生する簡単なコンポーネントを作ったりもしました。

tsubakit1.hateblo.jp

Unity公式の旧Animationを模したアニメーション再生コンポーネント

で、最近、旧Animationコンポーネントを模したアニメーション再生コンポーネントが、Unity公式Githubオープンソースで登場しました。

github.com

Animationと同じようなインターフェースで、ステートマシン無しにアニメーションが再生できます。

f:id:tsubaki_t1:20171113225653j:plain

 

アニメーション切替も超絶シンプル

またアニメーションの切替もAnimationと同じようなインターフェースで、ステートマシン無しにアニメーションが切替出来ます。

その際には、アニメーションには別途別名を設定して、そちらを使用して切り替えます。

gist.github.comf:id:tsubaki_t1:20171113225811j:plain

AnimatorのOptimised Game Objectも使える

SImpleAnimationはAnimator上で動作しているので、Mecanimで多少良い機能であるリターゲット(Humanoidなら大体使いまわせるアレ)や、Optimize Game Objectは使えます。少ないGameObjectで再生したり、着せ替えたりが便利です。ラグドール使えないけど。

f:id:tsubaki_t1:20171113230651j:plain

AnimationControllerとの共存は?

AnimatorにAnimationControllerをセットした状態でSimpleAnimationを使用すると、SimpleAnimationが優先されました。

これは運によるかもしれませんが、どちらも使う…という感じの事は無理なようです。

もしAnimationControllerで既に動作しているキャラクターにアニメーションを流し込みたいといった場合には、Timelineを使うのが良いかもしれません。

 

どちらにしろ

これで2Dでステートマシン制御という、無意味な縛りが無くなりました。

AnimationControllerにステートマシンを置いて遷移を書かない…みたいな、色々な意味で勿体無い実装ともオサラバです。

ヤッタネ!

f:id:tsubaki_t1:20171113233256g:plain

【Unity】ランダムにアニメーションを再生する

f:id:tsubaki_t1:20171108211656j:plain

Mecanim(Animator)を出来る限り活用してランダムにアニメーションを再生する方法についてです。

FacebookのUnityユーザー助け合い所で面白い話題が上がっていたので、試しに作ってみました。 

何時もと違うアニメーションの再生

主に待機モーション等、常に同じモーションではなく稀に違うモーションを仕込んでおくと、「凄い作り込みだ」みたいな反応になる事があります。

実際、多くのゲームでは稀に違うモーションを行ったり、コントローラーを投げ捨てて放置すると少し違った動きが仕込まれている事が多いです。

ランダムなアニメーションの再生

ランダムなアニメーションの再生を考えてみます。

一番手っ取り早いのは、スクリプトでランダムにアニメーションをPlayで再生してしまう事でしょう。ただ、今回はMecanimの機能を出来る限り使ってやってみます。

 

この使い方を少し応用すると、シーケンスを持ったBlendTreeを実現出来る気がしますが、それはそれ、これはこれ。

数値を指定して再生するアニメーションを決める

まずは、数値で再生するアニメーションを決める動きを実現してみます。

Animatorの再生アニメーション指定にはParameterを使用するわけですが、Parameterにintを使用するとequal(=)が使用出来ます。
これを使用して、アニメーション開始時に再生するアニメーションが選別出来るようになります。

f:id:tsubaki_t1:20171108212454j:plain

f:id:tsubaki_t1:20171108212909j:plain

サブステートマシンで擬似的なBlendTreeに

また構造を単純にするため、複数のアニメーションはサブステートにまとめておきます。これで、WAITのサブステートマシンにアニメーションを遷移すれば、Randomの値に従ってアニメーションを再生してくれるようになります。

f:id:tsubaki_t1:20171108213000j:plain

アニメーションを繰り返す

次に問題になるのが、アイドルモーションを「繰り返す」ようにする事です。今回の動作で期待するのは、延々と同じアニメーションをループするのではなく、アニメーションを繰り返しつつ、稀に違うアニメーションを行う事です。

 

この点でもSubStateMachineが有効に働きます。

やっているのは、SubStateMachineの遷移先を「自分」に指定している事です。これでExitでステートマシンから抜けた際に他のTransitionが無ければ再度Entryから入るようになります。

f:id:tsubaki_t1:20171108213232j:plain

ちなみに、ココで全てのコンディションがFalseになると、謎の動作になります。大抵の場合、一番親のEntryから再開しますが、稀に現在のStateに残ったりと色々とアレなので、そこんとこ注意です。

ランダムにParameterを切り替える

最後にParameterの値をランダムに切り替えてみます。

切り替える方法はMonobehaviour経由でやっても良いのですが、どうせSubStateMachineに入る瞬間に1回やれば良いので、StateMachineBehaviourでやってしまいます。

f:id:tsubaki_t1:20171108214052j:plain

gist.github.com

ここで面白いのは、「ステートに入った」時のコールバックとしてOnStateMachineEnterとOnStateEnterがある事です。

どちらもステートに入った時に呼ばれるコールバックですが、SubStateMachineにセットした場合少し異なります。

OnStateMachineEnterの場合はサブステートに入った時に1回、OnStateEnterはサブステート内でステートが変わる度に呼ばれます。

これの応用で、OnStateUpdateを親ステートにセットすれば、特定のSubStateに居る限り毎フレーム処理を呼び出したり出来ます。

 

ちなみに「OnStateMachineEnter」はあくまでEntry時なのでなのか、最初に再生するアニメーションがSubState内にあると動作しませんでした。
要するに、Animatorの起動時モーションはSubState以外である必要があります。

完成

ということで、Animatorの機能を出来る限り活用して、ランダムにアニメーションを再生するアプローチでした。

f:id:tsubaki_t1:20171108214452g:plain

 

そういえばUnity 2017.3からAnimatorがズーム出来るようになりました。個人的にはソレより検索と一覧表示が欲しい。切実に