テラシュールブログ

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

【Unity】知らないと面倒くさい事になるかもしれないAnimatorの「Write Defaults」の動作について

 今回はWrite Defaultsについて。

この挙動は少し分かりにくいので、少し補足します。

Write Defaultsという項目

f:id:tsubaki_t1:20170116000110j:plain

AnimatorのWrite Defaultsの項目のマニュアルを見ると、下のような物のようです。

Write Defaults : AnimatorStates を書くかどうかにかかわらず、その Motion によってアニメーション化されてないプロパティーによってデフォルト値に戻します。

 さて、「Motionによってアニメーション化されていないプロパティのデフォルト値」とは何でしょう。

キーが未定義なアニメーションは起動時のパラメータをデフォルト値として使う

プロパティのデフォルト値は、要するにAnimatorの起動時の位置やパラメータです。

AnimationClipが変更するオブジェクトや座標のパラメータを事前に保持しておき、特にキーが設定されていない項目は、その値を基準にブレンドを行うみたいです。

例えば下のGifアニメでは、最終的な座標(左下)のみを持つアニメーションを用意し、キーを何も持たないアニメーションからブレンドさせています。
Animatorを起動すると、デフォルト値はAnimator起動時の位置になるので、UIを配置した位置から最終的な座標(左下)へブレンドする形でアニメーションしています。*1

http://cdn-ak.f.st-hatena.com/images/fotolife/t/tsubaki_t1/20150205/20150205101008.gif

f:id:tsubaki_t1:20170116002224j:plain

Write Defaultsという項目

ネタバラシをすると、Write Defaultsの項目は要するに「アニメーションキーが設定されていない項目はデフォルト値を使用する」という項目です。

例えば下のようなUIを用意し、それぞれ「Sample 1のUIみ動かすアニメーション」「Sample 2のUIのみ動かすアニメーション」「Sample 3のUIのみ動かすアニメーション」を用意します。

f:id:tsubaki_t1:20170116003958j:plain

f:id:tsubaki_t1:20170116004112j:plain

このUIを動かすアニメーションを順番に再生すると、特にキーを設定しなくてもUIが仕舞われる感じのアニメーションが再生されます。

これはキーを設定していない項目はデフォルト値を元にブレンドしている為です。

f:id:tsubaki_t1:20170116004548j:plain

f:id:tsubaki_t1:20170116004403g:plain

逆にWrite Defaultのチェックを外していた場合、該当ステートではデフォルト値による上書きが無くなります。上のアニメーションの場合、UIを仕舞う挙動が無くなり、最後にアニメーションした位置がそのまま使用されます。

f:id:tsubaki_t1:20170116004809j:plain

f:id:tsubaki_t1:20170116004814g:plain

注意点

デフォルト値が保持されるケースの問題

なお保持するのはAnimationClipが変更する項目で、それ以外の項目は保持しないみたいです。保持するのは現在再生中のAnimationClipが変更するパラメータではなく、AnimationControllerが保持する全AnimationClipのいずれかが変更するパラメータです。つまり、AnimationControllerに含まれてるだけで効果を持ちます。

Write Defaultの有無に関わらず、AnimationClipで動かすパラメータはスクリプト上で動かす場合は注意が必要です。

tsubakit1.hateblo

デフォルト値がリセットされるケース

Write Defaultsを使用する上で一番の問題は、ここで使用するデフォルト値はAnimatorを含むGameObjectを非アクティブにするとリセットされ、アクティブ化した際のパラメータが利用されるという意味不明な仕様です。

例えばWrite Defaultsを使用中にGameObjectを一度非アクティブにすると、デフォルト値が変わってしまう為UIの切替が中途半端になります。

f:id:tsubaki_t1:20170116010217g:plain

tsubakit1.hateblo.jpので、Animatorを含むGameObjectの非アクティブ化は避け(親オブジェクトの非アクティブ化でも同様)、Animatorのみをdisableにしないと、ややこしい事が起こります。*2

f:id:tsubaki_t1:20170116012707j:plain

ちなみに、表情にBlendShapeを使いつつデフォルト値を前提に使用している場合、状態が混ざって面白い顔になる事があります。上のような感じ。
(他の表情が50とかの状態がデフォルト値となり、色々な表情が混ざる)

関連

tsubakit1.hateblo.jp

*1:この手法でUIを動かす場合、ブレンド率はリニア強制なので硬い動きしか表現出来ません。やるならブレンドツリーでやる事をお薦め。というかTweenお薦め

*2:正直、この仕様のせいでWrite Defaultsは死に機能になってる感がある

【Unity】AnimationControllerのAnyStateを使用してる際、現在のStateへ何度も移動しないようにする

今回は小さなTipsです。

f:id:tsubaki_t1:20170114000055g:plain

例えば上のように「どれか一つのUI状態を持つ」UIをAnimationControllerで管理し、かつAnyStateから呼び出すように作成した際、Triggerを叩くと何度もUI表示アニメーションが再生されてしまうといった事があります。

AnyStateの先へは何処からでも行ける

下Gifでは、UIの切替にAnyStateを使用してみましたが、ShowItem1が呼ばれる度にアイテムを表示するアニメーションが再生されてしまいます。

これはAnyStateの先に登録しているため、既にアニメーションが再生していた場合でもAnyStateへ戻り再度アニメーションを再生してしまう為です。

f:id:tsubaki_t1:20170113235304g:plain

Can Transition To Self

そんな時は、Transition(矢印)の設定にあるCan Transition To Selfのチェックを外します。これで、自身に遷移するアニメーションは無視されるようになります。

f:id:tsubaki_t1:20170114000259j:plain

f:id:tsubaki_t1:20170114000612g:plain

Triggerは使われないと消えない

この手法には一つ穴があります。それはTriggerはConditionの判定に使用された時に初めてチェックが外れるという仕様です。

例えばTriggerで次のステップへ移動する処理を作成しますが、Step2のみ時間移動とします。そうすると、Step2でTriggerが呼ばれてしまうと、Step3に移動した瞬間ステートを切り替えてしまいます。

f:id:tsubaki_t1:20170114001651g:plain

その為、Trigger実行中に他のステートに切り替えようとすると、一瞬別のステートに行きますがTriggerが再度判定されステートが戻ってくるといった事になります。

f:id:tsubaki_t1:20170114002124g:plain

ステート切替時にTriggerを消す

場当たり的な対処となりますが、ステート切替時にTriggerを消すと、この問題を回避出来ます。要するにStatemacihneBehaviourのOnStateExitのタイミングでTriggerを初期化すれば良いのです。

f:id:tsubaki_t1:20170114002505j:plain

gist.github.com

まぁ、ここまでしてAnyStateを使いたいかと言われると微妙な気もしなくもないですが…

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

【Unity】Unity-VR360-OverlayGridで、全方位写真の一部にポスターを貼ったり動画を仕込んだり

f:id:tsubaki_t1:20170112224424g:plain

今回は全方位写真(360度写真)で用意した風景の一部に動画を仕込む方法についてです。

全方位写真

全方位写真は、Googleストリート等でお馴染みの「マウス操作やVRヘッドマウントディスプレイで見渡す事の出来る」写真です。

周辺の情報を得たり、HMDを使うことで「まるで現地に居るような臨場感」を体験する事が出来ます。

f:id:tsubaki_t1:20170112225510j:plain

今回はこんな全方位写真のポスターや壁紙の変更、もしくは動画を仕込んでみます。

Unity-VR360-OverlayGrid

Unity-VR360-OverlayGridは、全方位写真に写真をハメ込む事の出来るアセットです。上手く設定すると、かなり馴染んだ感じで画像をはめ込む事が出来ます。

ちなみに、天井の模様、某超有名な映画のポスター、それとモニターがはめ込んだ動画です。結構わかりにくくなったんじゃないかなと。

f:id:tsubaki_t1:20170112230017j:plain

まずは全方位写真にポスターやモニターの中身をはめ込みます。

使い方(下準備)

まずは下のリンクから、Unity-VR360-OverlayGridを入手します。入手と言ってもパッケージとして公開されてる訳ではないので、Zipか何かでプロジェクトを落としてしまえば良いです。

github.com

f:id:tsubaki_t1:20170112230814j:plain

 

testシーンを開くと、中央の球体があります。その中が、全方位写真になっているので、球体の中に移動します。
ちなみに、ココで使用している画像はCubemapではなくTextureです。もし全方位写真を更新したい場合はSphereのTextureを差し替えれば良いです。

f:id:tsubaki_t1:20170112232131j:plain

f:id:tsubaki_t1:20170112232733j:plain

さて、さっそく全方位写真に物を配置していく訳ですが、ここで重要なポイントが、CameraとSceneViewのカメラの座標が(x:0, y:0, z:0)である事が望ましいという事です。

なので、メインカメラとSceneViewを中央へ移動させます。具体的には、MainCameraの座標を(x:0, y:0, z:0)に移動してもらい、Align View To Selectedでメインカメラの位置にシーンビューを移動させます。

この辺りの操作については Unity初心者が知っておくと少しだけ幸せになれる、シーンにオブジェクトを配置する時に使える18のTips+10 辺りを見てもらえると良いかと。

f:id:tsubaki_t1:20170112232552g:plain

使い方(物の配置)

次に全方位写真に物を配置していきます。

まずは空のGameObjectを座標(x:0, y:0, z:0)に配置し、VR360Gridコンポーネントをアタッチします。なおオブジェクトの名前は何でも良いです。

f:id:tsubaki_t1:20170112234723j:plain

次にVR360GridのPositionsを4つ以上に増やし、上手い感じに配置します。なお、Pos0が左上、Pos1が右上です。これを間違えると反転したり向きが逆だったりします。

上手く作れたらVR360Gridコンポーネント下にあるCreate Gridボタンを押してメッシュを構築します。

なお、構築後でもPositionsの位置は調整出来ます。

f:id:tsubaki_t1:20170112234916j:plain

後はMeshRendererのMaterialがNoneになっているので、好きな絵が貼ってあるマテリアルを設定すればOKです。

f:id:tsubaki_t1:20170112234526g:plain

より馴染ませる為に

より絵を馴染ませる為に、IBLの効果を活用します。

Skyboxを全方位写真と同じ内容の物に変更し、Direct Environment LightingをSkyboxに設定します。

f:id:tsubaki_t1:20170112235439j:plain

後はDirectional Lightのような光源を全て削除し、先程VR360Gridで作成したメッシュにLightingStaticのフラグを入れ、それらの光源処理をIBLにおまかせします。

これで、かなり色が馴染むようになります。

f:id:tsubaki_t1:20170112235827j:plain

動画を仕込もう(Unity 5.6版)

次は動画を仕込みます。折角なので、Unity 5.6で新しくなったVideoPlayerを使用します。VideoPlayerはMovieTextureと異なり、最初からテクスチャとして扱われないので、少し工夫します。
(特に何も設定しなければ、指定カメラの最前面もしくは背景としてムービーが流れます)

f:id:tsubaki_t1:20170113000927g:plain

マテリアルのMainTexにムービーを流し込む

レンダラーにVideoPlayerのムービーを流し込む一番手っ取り早い方法が、Material Overrideの設定でマテリアルの指定のテクスチャを上書きしてしまう方法です。

これで指定のマテリアルの任意のプロパティにVideoPlayerの内容が流し込めば、OKな訳です。

今回の場合は、Unity-VR360-OverlayGridで上書きしたテレビの画面にムービーの情報を流し込んでやれば良いです。

f:id:tsubaki_t1:20170113000549j:plain

f:id:tsubaki_t1:20170113001510g:plain

なお、動画はディスプレイなので、発光させたほうがソレっぽく見えるかもしれません。その場合はMaterialのEmissiveを弄るとか、まぁ臨機応変に。

感想

「全方位ムービーだと凄いデータが喰うので、一部のみを変更したい」みたいな場合や、「全方位写真に広告を仕込みたい」場合、後は全方位写真でも「ドアやタンス等に何らかのアクションを仕込みたい」場合、この技術は面白いかもしれません。

なおマニュアルがなかったので本来の使い方と異なる可能性がアリます。

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

 

【Unity】スケルタルアニメーション用のアセット、Anima2Dが無償公開

Anima2Dが、パブリッシャーがUnityTechnologiesになりUnity Anima2Dに名前を変えて無償公開されました。

f:id:tsubaki_t1:20170110234002j:plain

https://www.assetstore.unity3d.com/jp/#!/content/79840

 

Anima2Dはスケルタルアニメーション(FateGOやSprineのような物)を実現するアセットの一つです。

f:id:tsubaki_t1:20170111000315g:plain

www.youtube.com

操作方法

操作方法は、下のセッションがわかりやすそうな気がします。
個人的にも興味があるしゲームジャムに使いたいので、この辺りは後で調べます。

www.youtube.com

今後

Anima2Dは、公式ブログのコメント欄によると最終的にUnity標準のリグアニメーションに統合されていく予定みたいです。

Anima2D will remain as a separate package. However, together with Sergi (now in Team 2D) we are building this feature directly into Unity. The end result will be seamless and not a Unity with Anima2D preinstalled.

プリインストールする予定は無く、Unityに統合されるまではAssetStoreから入手する必要があるみたいです。

関連

blogs.unity3d.com

ちなみに、同時期にCine.Machine Base RigもパブリッシャーがUnityTechnologiesになり無償公開されました。

こっちはカメラのコントロールを行うアセットのようです。カットシーン風に使うと格好良い絵が撮れそうです。

f:id:tsubaki_t1:20170110235120j:plain

https://www.assetstore.unity3d.com/jp/#!/content/79898

vimeo.com

Cinemachine使って遊んでみる*1

http://sassembla.github.io/Public/2016:05:06%2015-01-52/2016:05:06%2015-01-52.html

*1:Githubの記事はURL貼るの面倒くさい…