Unity NGUIが描画順制御するときに何をしているかメモ

  • 2
    いいね
  • 0
    コメント

概要

いつも忘れるのでメモったものを残します。解釈が誤っていたら指摘をよろしくお願いします。NGUIのバージョンは3.11.1です。

NGUIの描画の仕組み

UIDrawCall.csの冒頭の#define SHOW_HIDDEN_OBJECTSのコメントアウトを外してUnityを再生すると分かりますが、NGUIはTexture,Sprite,Label(全てUIWidgetを継承)等を動的に生成したUIDrawCallオブジェクト(MeshRenderがアタッチされている)で描画しています。単純にMeshRenderに描画に必要な頂点、uv、マテリアル等を流し込んでいるだけです。このUIDrawCallオブジェクト一つが1ドローコールに相当します。またUIDrawCallオブジェクトは同一のマテリアルを持つものでまとめられます。(バッチング)

UIDrawCallと描画順

描画順は、基本はUIDrawCallのrenderQueueが制御しています。ここで言うRenderQueueは最終的にはMaterialクラスのrenderQueueに代入されるものです。NGUIではデフォルトではrenderQueueが3000から始まり、UIDrawCallオブジェクトが追加される毎にrenderQueueがインクリメントされていくイメージです。

UIDrawCall同士の描画順について

またUIDrawCallオブジェクトは、そのオブジェクトのTransform上の親にあるUIPanelが管理します。UIDrawCallは作成される順番でrenderQueueがインクリメントされていきますが、UIDrawCallの作成される順番はUIWidgetのdepthで制御されています。depth値の大きいUIWidgetの方が順番が後方になるのでrenderQueue値が大きくなり、描画順が後になるという感じです。

UIPanelと描画順について

UIPanelが2つ以上ある場合、UIPanelのdepth値が大きい方が描画順が後になります。つまり、UIPanelのdepth値の小さいUIPanelが管理しているUIDrawCallが先に追加されるので、UIPanelのdepth値が大きい方が描画順が後になります。

同一のUIDrawCallオブジェクト内の描画順

例えば同一アトラスの2つのスプライトが同じUIDrawCallにバッチングされたとしたら、その描画順はそのスプライト(UIWidget)のdepth値で決まるようです。決まるようですといったのは、depth値で決まる理屈がよく分からず、断言するまでの自信が無いということです。UIDrawCallにMeshに頂点を設定するとき(Mesh.SetVertices)の頂点の順番がUIWidgetの順番(depth値で決まる)に依存しており、多分この頂点の順番が描画順になっているのだろうと推測しています。