uGUIのボタンやイメージの間に、3Dの派手な魔法エフェクト(パーティクル)やキャラクターの3Dモデルを差し挟み、奥行きのある豪華なゲームUIを表現することは非常に一般的です。しかし、これを行うためにCanvasのレンダーモードを『Screen Space - Camera』に切り替えると、3DオブジェクトがUIの裏に隠れるか、逆に最前面に突き抜けるかして描画順が壊れる問題がほぼ確実に発生します。本記事では、この前後関係の破綻メカニズムを『演劇の舞台配置』の例え話を交えて分かりやすく解説し、完璧な重ね合わせを実現する設定手順を提示します。

1. 例え話で理解する:『舞台監督の設定ミスによる役者と背景板の激突』

この描画順の崩壊バグを直感的に理解するために、『演劇の舞台でのセットと役者の配置ミス』を例えに考えてみましょう。

あなたが演劇の舞台(ゲーム画面)を作っているとします。舞台の上には、手前でおしゃべりしている『役者(UIパネルやテキスト)』と、少し奥にある『巨大な書き割り/背景板(UI背景)』がいます。そして、その中間に『特撮用の煙エフェクト(3Dパーティクル)』を噴射させたいと考えました。

ここで、舞台監督(Unityのソートエンジン)が、それぞれの「立ち位置(カメラからの物理的な距離)」と「立ち入り許可証(Sorting Layer / Order in Layer)」の指示を曖昧にしたとします。仕分け人は『役者は最優先で手前に立つ(Canvasの描画順)』と認識していますが、煙を噴射するアシスタントは『カメラからどれくらい離れていればいいか(Plane Distance)』だけを基準に配置します。結果として、煙の噴射位置が役者より前に出てしまい、役者の顔の真ん前から煙が吹き出てしまったり(手前への突き抜け)、逆に背景板のさらに後ろの舞台裏で煙が空しく噴射されて誰の目にも届かなくなったり(奥への隠蔽)してしまいます。お互いが異なるルールで自分の立ち位置を決めているために、劇のビジュアルが崩壊してしまうのです。

このバグの根本原因は、『UI要素と3D Rendererが、描画順を決める際に異なる判断ルールを参照していること』にあります。UIはCanvas内のヒエラルキーの上下関係(Order)で順序を決定しますが、3D Renderer(パーティクルなど)はデフォルトでカメラからの「Z深度(物理的な距離)」で順序を決めます。この二つの異なる評価基準を同期させない限り、狙い通りの重ね合わせは不可能です。

2. 解決策A:Sorting LayerとOrder in Layerによる描画順の同期

最も確実かつ現代のUnity設計において推奨される解決法は、3Dオブジェクト側の Renderer に対し、『UIシステムと同じSorting LayerとOrderのルールを強制適用する』ことです。

設定手順:

  1. 対象のUI Canvasを選択し、インスペクターで『Canvas』コンポーネントの設定を確認します。
    • `Render Mode` が `Screen Space - Camera` であることを確認。
    • `Sorting Layer`(例: `UI` など)および `Order in Layer`(例: `10` など)の数値をメモします。
  2. UIの間に挟み込みたい3Dオブジェクト(パーティクルシステムやMesh Rendererなど)を選択します。
  3. パーティクルの場合は、『Renderer』モジュールを開きます。メッシュオブジェクトの場合は『Mesh Renderer』のインスペクターを確認します。
  4. Sorting Layer』の項目を開き、Canvasと同じレイヤー(例: `UI`)を割り当てます。
  5. Order in Layer』の数値を設定します。
    • もし、UI背景(Order = 10)と手前UIボタン(Order = 20)の「間」に表示したい場合は、3Dオブジェクトの `Order in Layer` を 『15』に設定します。

※オブジェクトが複数の子Renderer(複数のパーツに分かれたキャラクターモデルなど)を持つ場合は、親オブジェクトに『Sorting Group』コンポーネントを追加し、その中の Sorting Layer と Order in Layer を設定することで、子要素全体の描画順を一括で同期させることができます。

3. 解決策B:Plane Distance(カメラ面からの距離)の精密調整

もう一つの重要な要素は、カメラからUI Canvasまでの『物理的な距離』です。Canvasのインスペクターにある『Plane Distance』の設定値を確認してください。これは、カメラのレンズからUIまでの仮想的な距離(メートル)を表します。

もし `Plane Distance` が `100`(100メートル先)に設定されている場合、UIの間に挟みたい3Dオブジェクトのカメラからの相対距離(TransformのZ座標など)も、必ず `0` 〜 `100` の間の範囲(例: `50` など)に物理的に配置されていなければなりません。3DオブジェクトがZ座標 `150` の位置にあると、どれだけ `Order in Layer` を手前に設定しても、物理的にUI Canvasよりも奥にあると判定され、深度テストによって描画がカットされてしまいます。

基本設計として、`Plane Distance` はできるだけ小さく設定し(例: `5` や `10` など)、その極めて狭いカメラとCanvasの間の空間内に3Dオブジェクトを密着して配置するように設計することで、描画順が安定し、かつカメラワークによる位置ズレを防ぐことができます。