さけのさかなのブログ

同人ゲーム開発やってます。Unity使ったりする。

uGUIでモーダル

 ダイアログなんかを表示したとき、下にあるボタン類が押せなくなるアレを実装する。

 Unityは5.2.0f2。

※修正  非アクティブなときにも有効なのを修正しました

※修正2  Unity5.2.1対応コードを追記

ぱっと実装する

 alpha=0にしたImageを全画面に配置し、raycastTarget=trueにする(5.2以降)ことで、その下にあるGUIにクリックイベント等が飛ばないようにできる。

もうちょいマシにする

 上記のやりかただと、Imageは描画されないにも関わらずoverdrawが増えてしまい、いかにも良くない。

 ので、overdrawを増やさずにraycastをブロックするコンポーネントを作成する。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;

    public class Modal : Graphic
    {
        protected override void OnPopulateMesh(Mesh m)
        {
            m.Clear();
        }

        // Unity5.1までならこっち
        // protected override void OnFillVBO(List<UIVertex> vbo)
        // {
        //     // nop
        // }

        // Unity5.2.1ならこっち
        // protected override void OnPopulateMesh(VertexHelper vh)
        // {
        //    vh.Clear();
        // }

#if UNITY_EDITOR
        protected override void OnValidate()
        {
            base.OnValidate();
            UnityEngine.Assertions.Assert.IsFalse(m_Material, gameObject.name);
        }
#endif
}

TODO

  • Graphicのメソッドには、他にもoverrideしてnopにする余地はまだありそう。ちゃんと見てない。
  • CanvasRendererがRequireされるので無駄。だけど、Graphicを使う時点でどうしようもない。そもそもGraphicクラスではなく、イベント処理だけやるクラスでもあれば……。
  • パッドやキーボードによる操作がちゃんとブロックできるかは未確認。