uGUI 描画優先度のチートシート

皆様,こんにちは!
株式会社Aiming の 土井と申します!
リードソフトウェアエンジニアをやっております!

ここ数年は,業務で Unity の uGUI を使って UI 開発をする機会が多いのですが、
Order in Layer, Sorting Layer, ヒエラルキ上の並び順……(つд⊂)ゴシゴシ
Unity では重なり順を指定する項目が多いですよね。
これらの項目間の優先度が実際にどうなっているのか理解していなかったため、調査を兼ねてチートシートを作ってみました!

h2. 描画優先度を指定するものを列挙してみた

* Canvas の Screen Space 設定
* Order in Layer
* SortingLayer
* Camera の Depth 値
* Material の RenderQueue
* ヒエラルキ(Hierarchy) 上の親子関係・兄弟関係
* 座標の Z 値

どうやらこれらの関係を全て調べ上げれば良さそうです。

h2. チートシート

調べました。
画像は実際に Unity の GameView で表示されたもののキャプチャです。

これで、もう UI の重なり順で悩まない!

h2. 解説

h3. カメラ毎の優先度

* Canvas に設定された Camera による優先度
** ScreenSpace: Overlay 設定のものが最優先
** 次いで Depth 値が高いものが優先

h3. 同じカメラに設定されたキャンバス同士

* SortingLayer が高い Canvas が優先
** 同じ SortingLayer 同士では、 Order In Layer の値が高い Canvas が優先
*** さらに同じ Order In Layer 同士では、Z 値が低い(カメラに近い) Canvas が優先

h3. Mesh や パーティクルなど UI 以外の Renderer について

* SortingLayer や Order In Layer の値による重なり順の制御ができる
* ただし、SortingLayer と Order In Layer が同じ値を持つ Canvas がある場合、ヒエラルキ上の並び順による重なり順のソートは行われないので、 固有の Order In Layer 値を設定しよう

h3. Render Queue について

* UI の描画は、 RenderQueue = “Transparent” にて行われるため、独自のマテリアルを使用する場合は RenderQueue の値に 2501 以上を指定する必要がある

h2. 最後に

* UI のレイヤーの間に 3D モデルを表示したりエフェクトを出したりといった要件のときには、まず全体の UI のレイヤー構成を整理して仕様化しましょう。行き当たりばったりで重なり順をいじっていると混迷を極めます
* MeshRenderer などは標準でインスペクタ上から SortingLayer や Order In Layer が設定できません。
** https://docs.unity3d.com/ja/current/ScriptReference/Renderer.html
** 自前でスクリプトから設定する必要があります
*** (Order In Layer は sortingOrder というプロパティです)

おしまい。