チュートリアルなど作るときに、タップやクリックさせたい部品だけ残して他を暗転させるのはよく見ると思います。
Unityでは デフォルトシェーダでステンシルバッファを使えば 意外と簡単に実現できます。
- 1. フェードアウト用の黒いパネルを用意する
- 2. マテリアルを2つ用意する
- 3. 画像にマテリアルを設定する
- 4. スクリプトからフェードアウトさせる
- 5. さらに一部だけフェードアウトさせたい場合
- 仕組みを知りたい方
1. フェードアウト用の黒いパネルを用意する
まずシーン内に以下のようにヒエラルキーを構成します。
GaugeRoot がフェードアウトさせたくない要素(冒頭GIFの左上のゲージ)。
FadeImageは カンバス全体をおおう真っ黒な Image で、これの透明度を操作することで画面全体のフェードアウトができます。オブジェクト構造の一番下に置いて、一番手前に描画されるようにしています。
2. マテリアルを2つ用意する
プロジェクトビューで Create > Material とクリックし、マテリアルを二つ 用意します。
シェーダは二つとも UI/Default にします。
フェードアウト用黒画像のマテリアル
フェードアウト画像用のマテリアルは以下のように設定します。
ここでは Stencil Comparison の値を3にしているだけです。
フォーカスしたい画像用のマテリアル
もう一つのほうは以下のように設定。
まず Stencil Comparison の値がデフォルトの 8 になっていることを確認。
次に Stencil Operation を 3 にします。
ついでに Use Alpha Clip にチェックを入れておきましょう。
3. 画像にマテリアルを設定する
UIはImageコンポーネントで構成されていると思うので、フェードアウト用画像と、フォーカスしたい画像 全て のImageコンポーネントにそれぞれマテリアルを設定します。
これで準備は完了。
4. スクリプトからフェードアウトさせる
フェード黒画像にアタッチしたマテリアル に対し、アルファ値を増減させてフェードアウトさせます。以下、サンプルコード。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FadeScript : MonoBehaviour { [SerializeField] Material FadeMaterial; void Start () { StartCoroutine(FadeRoutine ()); } IEnumerator FadeRoutine () { // 黒+全透明に初期化 Color bl = Color.black; bl.a = 0; FadeMaterial.color = bl; // 黒くフェードさせるループ while (FadeMaterial.color.a < 0.8f) { yield return null; Color col = FadeMaterial.color; col.a += 0.02f; FadeMaterial.color = col; } } }
5. さらに一部だけフェードアウトさせたい場合
こんなかんじで「フォーカスしているUIの中の一部はフェードアウトさせたい」という欲張りさんは、もう一つマテリアルを用意しましょう。
これとの合わせ技も面白いですね
仕組みを知りたい方
Unityの ステンシルバッファ という仕組みを使っているので、興味のある方はドキュメントを追うとおもしろいです。
マテリアルに設定した値ですが、マニュアルには載っていないです。Unity Forum に解析した神がいたので参考にどうぞ。
https://forum.unity.com/threads/stencil-op-comparison-values.362425/
対応しているシェーダ命令は以下参照。