いんでぃーづ

個人でゲーム開発してる上で吸収したモノたち紹介。UnityからGIMPまでなんでも。デザインとかゲーム論まで語っちゃうよ的なアレ。

Unity UI:一部分だけ残してフェードアウトさせる

{スポンサーリンク}

チュートリアルなど作るときに、タップやクリックさせたい部品だけ残して他を暗転させるのはよく見ると思います。
Unityでは デフォルトシェーダでステンシルバッファを使えば 意外と簡単に実現できます。

f:id:sugar_affordance:20180522121409g:plain

1. フェードアウト用の黒いパネルを用意する

まずシーン内に以下のようにヒエラルキーを構成します。

f:id:sugar_affordance:20180522121610p:plain

GaugeRoot がフェードアウトさせたくない要素(冒頭GIFの左上のゲージ)。
FadeImageは カンバス全体をおおう真っ黒な Image で、これの透明度を操作することで画面全体のフェードアウトができます。オブジェクト構造の一番下に置いて、一番手前に描画されるようにしています。

2. マテリアルを2つ用意する

プロジェクトビューで Create > Material とクリックし、マテリアルを二つ 用意します。
シェーダは二つとも UI/Default にします。

f:id:sugar_affordance:20180522124817p:plain

フェードアウト用黒画像のマテリアル

フェードアウト画像用のマテリアルは以下のように設定します。

f:id:sugar_affordance:20180522123238p:plain

ここでは Stencil Comparison の値を3にしているだけです。

フォーカスしたい画像用のマテリアル

もう一つのほうは以下のように設定。

f:id:sugar_affordance:20180522123607p:plain

まず Stencil Comparison の値がデフォルトの 8 になっていることを確認。

次に Stencil Operation3 にします。

ついでに Use Alpha Clip にチェックを入れておきましょう。

3. 画像にマテリアルを設定する

UIはImageコンポーネントで構成されていると思うので、フェードアウト用画像と、フォーカスしたい画像 全て のImageコンポーネントにそれぞれマテリアルを設定します。

f:id:sugar_affordance:20180522123855p:plain

これで準備は完了。

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. さらに一部だけフェードアウトさせたい場合

f:id:sugar_affordance:20180522125302p:plain

こんなかんじで「フォーカスしているUIの中の一部はフェードアウトさせたい」という欲張りさんは、もう一つマテリアルを用意しましょう。

f:id:sugar_affordance:20180522125359p:plain

これとの合わせ技も面白いですね

indie-du.com


仕組みを知りたい方

Unityの ステンシルバッファ という仕組みを使っているので、興味のある方はドキュメントを追うとおもしろいです。

docs.unity3d.com

マテリアルに設定した値ですが、マニュアルには載っていないです。Unity Forum に解析した神がいたので参考にどうぞ。

https://forum.unity.com/threads/stencil-op-comparison-values.362425/

対応しているシェーダ命令は以下参照。

Unity - Scripting API: StencilOp

Unity - Scripting API: CompareFunction

Amazon.co.jpアソシエイト