テラシュールブログ

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

【Unity】SpriteMaskでSpriteにマスクを掛ける演出が色々と面白い

Unity 2017.1より追加されたSpriteMaskの機能が意外と面白いので、少しメモします。

SpriteMask

SpriteMaskはSpriteを利用してSpriteRendererにマスクをかける機能です。
画像をSpriteの形にくり抜いたり、逆にSpriteをくり抜いたり出来ます。

f:id:tsubaki_t1:20170721003252j:plain

機能的には現状存在するSpriteに対してマスクを掛ける…程度の機能ではありますが、意外とコレは利用の幅が広そうです。

 

操作方法

使い方に関しては正直マニュアルが詳しいです。

docs.unity3d.com

壁に穴を開ける

壁に穴を空けてみます。これはUnityTipsに上がっていたものを自分なりに解釈したものです。

f:id:tsubaki_t1:20170721003328g:plain

まず最初の状態がコレです。

SpriteMask等は何も設定していないので、キャラクターの前面に地面が表示されています。

f:id:tsubaki_t1:20170721003954j:plain

次にSpriteMaskをキャラクターの子GameObjectに追加し、キャラクターの前面の地面のSpriteRendererにはMaskIntaraction Visible Outside Masksを設定します。

SpriteMaskをキャラクターの子GameObjectに設定するのは、そのほうが柔軟にマスクする範囲を決められるからです。

f:id:tsubaki_t1:20170721004310j:plain

f:id:tsubaki_t1:20170721004301j:plain

 

後はマスクで抜いた先の背景も設定しておきます。
背景はキャラクターよりOrderInLayerが奥のSpriteを用意しておき、そのMask Interactionはnoneに設定しているだけです。

これでマスクでくり抜いたら背景がいきなり空…みたいな事は回避出来ます。

f:id:tsubaki_t1:20170721004558j:plain

同様に、SpriteMaskを使用してシルエットを表示させる事も可能といえば可能です。ただしシルエット色を変えられる以外のメリットが無いので、ソレをするならStencilでやった方が良いんじゃないかなという気はします。

Spriteの消滅演出をSpriteMaskで

マスクはアルファのカットアウト(アルファブレンドではない!)で、SpriteMaskのα値を変えればスプライトの消滅演出を追加したり出来ます。

例えば下の場合、簡単なルール画像を用意すれば実現出来ます。

f:id:tsubaki_t1:20170721010817g:plain

For You さんのページよりルール画像を入手して、ルール画像の透明度ルールはFrom Grayscaleに変更。

後はSpriteMaskのAlpha Cutoutを設定すれば、うまい感じに切り抜いてくれます。

ただ、ルール画像によっては最後まで綺麗に切り抜いてくれない事があるので、そのあたりが出たらルール画像を調整する必要があるかもしれません。

f:id:tsubaki_t1:20170721011116j:plain

実はパーティクルのマスクも出来る

もう一つ面白いのが、実はSpriteだけではなくParticleSystemにもマスクが使えるという点です。例えば下のように、パーティクルの生成をマスクの形でカットしています。

f:id:tsubaki_t1:20170721010048g:plain

f:id:tsubaki_t1:20170721011935j:plain

ただひとつ問題になるのがSpriteMaskが複数合った場合です。
例えば下の図では、右下の赤いパーティクルと左上の黄色いパーティクルが、お互いのマスク範囲内に混ざってしまっていることが確認出来ます。

f:id:tsubaki_t1:20170721011612j:plain

これはSortingGroupで解決出来るみたいです。てっきりSprite用かと思ってましたが、意外と使えるもんです。

親にSortingGroup、子にSpriteMaskとParticleを配置すると、上手い感じにパーティクルをマスクしてくれます。

f:id:tsubaki_t1:20170721011845g:plain

f:id:tsubaki_t1:20170721083548j:plain

tsubakit1.hateblo.jp

関連

tsubakit1.hateblo.jp

halcyonsystemblog.blog.fc2.com

tsubakit1.hateblo.jp

【Unity】ダッシュで移動した際の土煙っぽい表現

f:id:tsubaki_t1:20170719210027g:plain

今回はキャラクターが移動した時の土煙について、よく考え方を忘れるのでメモしておきます。

移動時の土煙

自分の好きな演出の一つに「移動時の土煙」という物があります。
これは漫画やアニメ等で良くあるダッシュで移動した事を表す記号で、キャラクターの移動速度や軌跡を上手く表してくれます。

f:id:tsubaki_t1:20170719210633g:plain

煙の表現ですが、以前は基本的にアルファブレンドで煙のテクスチャをばら撒いていましたが、最近はCubeをばら撒くのがマイブームです。

ので、Cubeをばら撒くアプローチの方法について書いておきます。

f:id:tsubaki_t1:20170719211225j:plain

土煙の表現

土煙の表現を行う際に一番手っ取り早いアプローチは、ParticleSystemを使う事でしょう。とりあえずこの4つのモジュールを使います。

f:id:tsubaki_t1:20170719210915j:plain

作ったパーティクルは、動くキャラの足元から少し上辺りにおいておくと良いです。

向きと大きさはランダム、座標はワールド

まず基本的な部分ですが、Simulation SpaceがWorldになってる事です。これで向きを変えた時もLocal座標ではなくWorld座標でParticleを生成してくれます。便利便利

f:id:tsubaki_t1:20170719211402j:plain

もう一つ、StartSizeとStart Rotationを操作して開始時の向きを切り替えておきます。

この項目は初期値と違って範囲指定出来るようにしてあります。これは、項目右の▼から設定できます。

回転やサイズは固定でもある程度見栄えは付きますが、やはりココはランダムであって欲しいという、コダワリポイントです。

f:id:tsubaki_t1:20170719212420j:plain

移動時の生成量

移動時の生成量を設定します。Rate over Distanceで移動に応じてパーティクルを出してくれるようになるので、コレを使ってキャラクターが移動したときに足元にパーティクルを出してもらいます。

f:id:tsubaki_t1:20170719211710j:plain

足元辺りに生成する

Shapeで出現位置を少しランダムにします。演出的には無くてもそれ程変わらないといえば変わらないのですが、合ったほうが多少は良い感じの見栄えになる印象です。

f:id:tsubaki_t1:20170719212540j:plain

範囲は足の範囲くらいが良いです。場合によってはEdgeやCircleでも良いかもしれません。

最初は小さく、一気に膨らんで、最後は縮んでく

Size Over Lifetimeで、最初は小さいが一気に膨らみ、段々小さくなるようにします。このさじ加減で演出が大体決まります。

f:id:tsubaki_t1:20170719212721j:plain

パーティクルとして生成するのはモデル

こんかいの演出ではCubeを生成しています。理由はそのほうがカッコイイからです。
一応、Meshのパーティクルはそこそこ重い部類に当たるので、注意して使ったほうが良いです。

モデルなのでStandardShaderも気にせず使います。頂点カラーが使えませんが、今は気にしません。

f:id:tsubaki_t1:20170719213002j:plain

後は影を落とし、かつ影を受ける設定です。

これで完成

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

【Unity】低解像度に設定したRenderTextureを使いつつ、クリックした位置にキャラクターを動かす

f:id:tsubaki_t1:20170718221658g:plain

今回はRenderTexturerを使用しつつ、クリックした位置にRayを飛ばし移動させるアプローチについて色々と見てみます。

低解像度なRenderTextureでゲームを描画する

ゲーム画面を低解像度に設定する為にRenderTextureを使うのは良いアイディアの一つです。このアプローチを使えばUIは高解像度のままハイクォリティで描画不可の高いシェーダーやポストエフェクトを割りと安く使用できます。

個人的な考えで言えば、モバイルのような小さな画面で軽いシェーダーをFHD(1920×1080)で描画するより、リッチなシェーダーをHD(1280×720+MSAA)で描画するほうがハイクォリティと見られるんじゃないかって気がしてます。*1

 

f:id:tsubaki_t1:20170718224401j:plain

低解像度StandardShader vs 高解像度Mobile Shader

 

ただ、画面全体を低解像度化するとUIが低解像度になります。低解像度なUIはエッジ部分が目立ってしまうので余りやりたくない事の一つです。特に文字が目立ちます。

ので、描画負荷の上がりやすいゲーム画面は少し低解像度で、エッジの見えやすいUIは高解像度で描画するアプローチを使います。

f:id:tsubaki_t1:20170718223246j:plain

Camera.main.ScreenPointToRayがおかしくなる

さて、このアプローチを行った場合Camera.Main.ScreenPointToRayの値がおかしな値を返して来ます。
例えば下のようなコードです。640x480の画面に対して320x240のRenderTextureを使用して描画していると、クリックの位置に向かうはずが、違う位置で動いてしまっています。

var ray = Camera.main.ScreenPointToRay ( Input.mousePosition);
if (Physics.Raycast (ray, out hit)) {
    agent.SetDestination (hit.point);
}

f:id:tsubaki_t1:20170718224928g:plain

 理由はシンプルで、Input.MousePositionはフル解像度の位置を示していますがRenderTextureで画面は縮小されているので、位置がズレています。

Input.MousePositionの位置を補正してやる

思いつく解決方法は二つ。Input.MousePositionの位置を補正してやるか、ViewPort座標を使用するかです。
今回は手っ取り早い解決法でViewport座標を使用してみます。

 

Input.MousePositionで取得した位置をScreenのサイズで割り、位置を0~1の値に正規化します。後は、正規化したInput.MousePositionの座標を使用してViewportPointToRayでRayを生成、Raycastに与えます。

 

下のコードでは、cursorに動かしたいオブジェクト、rtCameraにRenderTextureをセットしたカメラを指定すると、低解像度化したRenderTextureを使用してもマウスの位置までCursorを動かしてくれます。

gist.github.com

f:id:tsubaki_t1:20170718231109g:plain

tsubakit1.hateblo.jp

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

www.slideshare.net

*1:ちなみに最近のスマホは「解像度を変更できる」機能があったりするみたいです。galaxys7とか

【Unity】"Default Playables"で、VideoPlayerやTextをタイムラインで制御したりFadeoutやTweenしたり

f:id:tsubaki_t1:20170714204325j:plain

Timelineのサンプルが公開されました。

Default Playablesの入手

UnityのTimelineに、幾つかのサンプルPlayableを追加するアセットが公開されました。

以下のURLからダウンロードできます。

https://www.assetstore.unity3d.com/en/#!/content/95266

 

なお、サンプルシーンは含まれません。マニュアル(英語)も中途半端なので、Timelineの使い方を覚えてから見る事をお勧めします。

Default Playablesで出来ること

割とあったら便利機能が含まれてます。

何故これをエディターに含めなかったし

VideoPlayerのTimeline制御

任意のタイミングで任意のClipを再生する事ができます。挙動的に複数のムービーのフェード切り替えも出来るハズですが、うまく動作しませんでした。

f:id:tsubaki_t1:20170714210745g:plain

tsubakit1.hateblo.jp

LightのTimeline制御

ライトの色や輝度、範囲を指定出来ます。

f:id:tsubaki_t1:20170714210831g:plain

なお、Lightmapにauto generateが付いてると物凄い勢いでライトの再構築が走るので、auto generateは外しておくが吉です。

まぁ、auto generateはシーン読込時に読まれない致命的なバグ(Unity5リリース時からある)があるので、殆どの人はdisableにしてると思いますが。

シーケンスのタイミング内にある時にSetDestinationしまくるだけです。

TimelineのPreviewも使えず、移動中に向きが変わると移動が破綻します。

TextSwitcher

指定したタイミングで指定した文字にテキストを切り替えます。字幕等の制御に使えるかもしれません。

色とサイズをフェードする事が可能ですが、この方法でフォントのサイズをフェードすると、一瞬でフォントテクスチャの再構築が走るので、サイズのフェードは使ってはいけません(モバイルは)

f:id:tsubaki_t1:20170714212728g:plain

tsubakit1.hateblo.jp

Transform Tween

オブジェクトのTween制御です。

開始点・終了点を指定するとTweenしてくれる他、シーケンスを混ぜることで2つのTweenの中間点を行ってくれます。要するに下のようにカーブします。

Timelineの謎仕様の一つである「一つ前のシーケンスを取れない(取れるには取れるが物凄い大掛かりになる)」により、全てのシーケンスに開始点と終了点をセットする必要があります。

f:id:tsubaki_t1:20170714213248g:plain

tsubakit1.hateblo

ScreenFader

UIの色を変えます。

UIのImageを画面全体に設定しておくと、フェードっぽい事が出来ます。

但し、Imageの値を操作しているので「UIの再構築」が普通に走ります。本当はこれはCanvasGroup(UIの再構築が走らず、α 0でUIが消える)でやるべきなのですが…

色指定でのフェードなので、フェード先の色は自由に決められます。

f:id:tsubaki_t1:20170714214129g:plain

Time Dilation

TimeのSpeedを制御します。Fixed Time stepを操作しないので、物理演算が入っていると酷い絵になります。

一応フェードも可能なので、ゆっくり時間の速度を戻すことも期待出来ます。

f:id:tsubaki_t1:20170714213932g:plain

tsubakit1.hateblo.jp

感想

いくつか微妙な所もありますが、サンプルとしては分かりやすいかもしれません。幾つかのサンプルはゲームを再生しないと動かないので、実際に使うのはかなりシンドイかもしれません。

今回はParticleの制御は含まれていませんでしたが(フォーラムで公開されてる)VideoPlayerのTimeline制御は、実際かなり良い所をついていると思うので、とても期待があります。

関連

www.youtube.com