【Unity】Sprite Maskを使ってSpriteやParticleを切り抜く方法(2019.3)

f:id:Effect-Lab:20191124235622p:plain

 

こんにちは。

 

今回はSprite Maskを使ってSpriteやParticleを切り抜く方法です。

 

Sprite Maskを使うと、下図のようにSpriteを切り抜いたり、

f:id:Effect-Lab:20191123005641g:plain

 

Particleも一緒に切り抜いたりができます。

f:id:Effect-Lab:20191123034017g:plain

 

この記事は、スプライトについて書いた以下の過去記事の内容を理解している事を前提に書いています。
これらの記事には、スプライト用のテクスチャ設定、描画順の変更、グルーピングの方法などが書いてありますので、もし本記事で分からない事があれば参考にしてみて下さい。

  

  

マスク用の「Sprite Mask」を作る

基本的な使い方は公式マニュアルでも詳しく解説しているので御覧ください。

docs.unity3d.com

 

マスクで切り抜くには、まず「Sprite Mask」オブジェクトを作る必要があります。
手順はメインメニューの「GameObject > 2D Object > Sprite Mask」で作れます。

f:id:Effect-Lab:20191121000945p:plain

 

すると「New Sprie Mask」というオブジェクトがSceneに追加されます。

f:id:Effect-Lab:20191123004125p:plain

 

ここで気をつけたいのですが、「2019年11月21日」時点での公式マニュアルは、2019.3.0b4バージョンでInspectorに表示されるプロパティ内容と少し違っています。
下図が2019.3.0b4バージョンのプロパティです。

f:id:Effect-Lab:20191121000401p:plain

 

Custom Rangeは最初のフラグは最初オフになっていますが、オンにするとSorting LayerやOrder in Layerなどの項目が開きます。

 

公式マニュアルに書かれていない箇所に関しましては追って解説していきます。

 

Sprite MaskはSpriteがそのまま使えます。指定する箇所は下図になります。
同じテクスチャが流用できますね!

f:id:Effect-Lab:20191121001600p:plain

 

 

Spriteをマスクで切り抜いてみる

さきほど作成したSprite Maskに、切り抜きたい形のSpriteを指定します。

f:id:Effect-Lab:20191123011743p:plain

今回マスクに使うのはこのようなSpriteです。

f:id:Effect-Lab:20191125002620p:plain

 

次に、このマスクで切り抜きたいSpriteにマスクを有効にする設定をします。

 

マスクを有効にするには、Spriteのプロパティで、「Mask Interaction」を変更します。

f:id:Effect-Lab:20191123012143p:plain

 

この項目には以下の3つの設定があります。
(四角いSpriteに対して丸いマスクをかけています)

 

None:マスクの影響を受けない

f:id:Effect-Lab:20191123012611p:plain

Visible Inside Mask:マスク範囲の外側を切り抜く

f:id:Effect-Lab:20191123012616p:plain

Visible Outside Mask:マスク範囲の内側を切り抜くf:id:Effect-Lab:20191123012622p:plain

 

Spriteが複数ある場合でもそれぞれのSpriteのMask Interactionを設定する事で、下図のように全てのSpriteに対してマスクをかけることも可能です。

f:id:Effect-Lab:20191123013159p:plain

 

※Sprite側の設定しだいでは、もしかしたら参考画像のようにマスクが効かないかもしれません。
その原因はSpriteとSprite MaskのSorting LayerやOrder in Layerが関係している可能性が高いです。
それらの関係に関してはもうちょっとだけ後に解説しますので、今うまくいかない方はそちらの解説を見た後にもう一度お試しください。

  

 

Particleをマスクで切り抜いてみる

f:id:Effect-Lab:20191124133310g:plain

 

上図のように、マスクはParticleにも反映させる事ができます。

 

設定は簡単で、Particleプロパティの「Renderer > Masking」でSprite同様にマスクを有効にするかどうかが選べます。

f:id:Effect-Lab:20191124134754p:plain

 

設定はこれだけです!

 

 

マスクをかける範囲をコントロールする

Sprite Maskは、デフォルトの状態だと全てのSpriteやParticleを切り抜きます。(※マスクの影響を受けさせる設定をしたオブジェクトに限ります)

 

それが都合が良い場合もありますが、特定のオブジェクトにだけマスクをかけたい場合もあると思います。

 

その場合には、以下の4つの方法で解決する事ができます。

  • Sorting Layerを使う
  • Order in Layerを使う
  • Z値を使う
  • Sorting Groupを使う

 

次からはそれぞれの方法を詳しくみていきます。

 

 

マスクをかける範囲をレイヤーで設定する場所

Sprite MaskのプロパティでCustom Rangeのフラグをオンにすると、下図のように「Sorting Layer」と「Order in Layer」を設定する項目が現れます。

f:id:Effect-Lab:20191124150625p:plain

 

ここで注目したいのが、「Front」「Back」です。

 

Sprite Maskは、マスクの範囲を前と奥それぞれ設定する事で、その間に描画されるオブジェクトに対してマスクをかけるという調整が可能です。

 

 

Sorting Layerを使ってマスクの範囲をコントロールする

まずは「Sorting Layer」を使った例を見てみましょう。


検証用に5つのSorting Layerを作り、各オブジェクトにこのレイヤーを割り当てています。(各オブジェクトのZ値は0、Order in Layerの値も0にしています)

f:id:Effect-Lab:20191124153741p:plain

 

赤●が一番奥、Particleが一番手前に描画されています。

 

この状態でFrontを「Triangle」に変えてみると、青▲までマスクで切り抜かれました。

f:id:Effect-Lab:20191124152928p:plainf:id:Effect-Lab:20191124152808p:plain

 

「Square」に変えてみると、マスクの範囲がSquareまで広がったので緑◼まで切り抜かれるようになりました。

f:id:Effect-Lab:20191124154015p:plainf:id:Effect-Lab:20191124154008p:plain

 

今度はBackの方を試してみましょう。
Backを「Circle」にしてみると、赤●がマスクの範囲から外れました。

f:id:Effect-Lab:20191124154521p:plainf:id:Effect-Lab:20191124154652p:plain

 

「Triangle」に変えてみると青▲もマスクの範囲から外れました。

f:id:Effect-Lab:20191124154533p:plainf:id:Effect-Lab:20191124154700p:plain

 

このように、マスクのSorting LayerのFrontとBackを使ってマスクの範囲をコントロールする事ができます。

 

 

ここで一点だけ注意したい事があります。
それは、Particleに対してはちょびっとだけ処理が変わるという事です。

 

下図はFrontを「Particle」に設定した例ですが、Particleにはマスクがかかっていませんね。
f:id:Effect-Lab:20191124161149p:plainf:id:Effect-Lab:20191124161156p:plain

 

Spriteに対しては指定したSorting Layerまでがマスクの範囲に含まれたのですが、Particleに対してはもう一つ前面のレイヤーまで指定しないとマスクの範囲に含まれないようです。

 

という事で下図のように「Front」にしてみました。
このSorting LayerはParticleレイヤーよりも前面にあるので、これで無事にParticleに対してもマスクがかかるようになりました。

f:id:Effect-Lab:20191124162120p:plainf:id:Effect-Lab:20191124162111p:plain

 

 

Order in Layerを使ってマスクの範囲をコントロールする

次は「Order in Layer」を使った例を見てみましょう。

検証に使うのは先程と同じオブジェクトですが、今回はSorting Layerを全て「Default」にして、Order in Layerの値で描画順を設定しました。

f:id:Effect-Lab:20191124162738p:plain

 

Order in Layerの値はそれぞれ以下のようにしてあります。
赤●が一番奥、パーティクルが一番手前に描画するようにしています。

  • 赤●:0
  • 青▲:10
  • 緑◼:20
  • パーティクル:30

 

まずはFrontのOrder in Layerを「15」にしてみましょう。
Order in Layerが15以下の青▲までがマスクの範囲に含まれました。

f:id:Effect-Lab:20191124164811p:plainf:id:Effect-Lab:20191124164818p:plain

 

ここでちょっと疑問なのが、なぜ青▲はマスクされて赤●はマスクされないのか?です。

 

答えは、BackのOrder in Layerの値が0で、赤●のOrder in Layerの値と同じだからです。

 

という事で、Backの方を「-1」に変更してみましょう。
すると赤●もマスクの範囲に入りました。

f:id:Effect-Lab:20191124170333p:plainf:id:Effect-Lab:20191124170340p:plain

 

この調子でFrontの方の値を上げていくと、その値以下のオブジェクトがマスクの範囲に含まれていきます。

f:id:Effect-Lab:20191124171014p:plainf:id:Effect-Lab:20191124171011p:plain

f:id:Effect-Lab:20191124171021p:plainf:id:Effect-Lab:20191124171017p:plain

 

さらに、Backの方の値を上げる事で奥側のマスク範囲を狭めて、下図のように切り抜く事も可能です。
下図の設定は、15より大きく、35以下のOrder in Layerに対してマスクをかけるという意味になります。

f:id:Effect-Lab:20191124171024p:plainf:id:Effect-Lab:20191124171027p:plain

 

 

Z値を使ってマスクの範囲をコントロールする

SpriteのSorting LayerとOrder in Layerが同一の場合、Z値によってマスクの範囲を設定する事ができます。

 

下図は赤●、青▲、緑◼をZ軸に対してズラして配置し、Sprite MaskをZ軸に対して前後に移動している状態です。

f:id:Effect-Lab:20191124190116g:plain


図形3つのSorting Layerは「Default」Order in Layerは「0」となっています。

この時、Sprite Maskは下図のようにBackのOrder in Layerを「-1」としています。
(※どちらも0だとマスクがどこにも効かないからです)

f:id:Effect-Lab:20191124192323p:plain

 

Z値を使った描画順コントロールの場合、Spriteの描画順の時と同様、Particleに対してマスクを有効か無効かのコントロールができません。
Particleも含めた表現をしたい場合は、「Sorting Layer」か「Order in Layer」でコントロールをするのが良さそうです。

 

 

マスクをかける範囲をSorting Groupで設定する

Sorting Groupの機能を使えば、任意のグループにだけマスクをかけるという事が可能です。

 

やり方は簡単で、下図のようにSprite MaskとSpriteを一緒にSorting Groupコンポーネントが付いたオブジェクトの子供にするだけです。

f:id:Effect-Lab:20191124192543p:plain

 

3つの図形オブジェクトはSorting LayerもOrder in Layerも同じですが、同グループの赤●と青▲だけがマスクで切り抜かれています。

f:id:Effect-Lab:20191124192840p:plain

 

このように便利なSorting Groupですが、Particleに関してはグループに含めてもグループ内でのマスクコントロールが効きません。

 

例えば下図のように同グループ内にParticleとSprite Maskが含まれてる場合はParticleにマスクがかかりませんが、

f:id:Effect-Lab:20191124193606p:plain

下図のようにSprite Maskがグループ外にある場合はSorting Group全体にマスクがかかるのでParticleにもマスクがかかります。

f:id:Effect-Lab:20191124193608p:plain

 

マスクでParticleを使う場合は、これらの事を踏まえて作成する必要がある事を覚えておきましょう。

 

 

Alpha Cutoffとは?

マスクの範囲についての解説はこれで終わりですが、最後に「Alpha Cutoff」についての解説をしましょう。

 

この機能は、Sprite Maskのアルファ値がAlpha Cutoffの値より大きいピクセルに対してマスクをかける機能です。

 

例えば、下図のような0~1のアルファ値を持つテクスチャを使用した場合、

f:id:Effect-Lab:20191124220525p:plain

下図のような挙動になります。

f:id:Effect-Lab:20191124220711g:plain


マスク用テクスチャを工夫すれば、以下のようないろんなマスク表現が可能になります。

f:id:Effect-Lab:20191124221507p:plain f:id:Effect-Lab:20191124221513g:plain

f:id:Effect-Lab:20191124221847p:plain f:id:Effect-Lab:20191124221854g:plain

f:id:Effect-Lab:20191124222415p:plain f:id:Effect-Lab:20191124222424g:plain

 

 

おわりに

いやー、このマスク機能はなかなか便利な機能ですね!

 

2Dゲームはもちろんですが、3DゲームでもSprite、SpriteMask、Particleを組み合わせる事でカットインやトランジションのような2D演出に使えるかと思いますし、工夫次第では通常の3Dエフェクトにも使って面白い表現ができるかもしれません。

 

Alpha Cutoffもテクスチャ次第でいろんなマスクアニメーションが作れそうですね!

 

 

マスクについて学ばせていただいたサイト

tsubakit1.hateblo.jp

kan-kikuchi.hatenablog.com