CanvasDirector

自動でSortingOrderを調整したい!

 各UIのSortingOrder設定を覚えていられない! そのUIの配下にあるParticleSystemや子CanvasのSortingOrder設定なんてもっと覚えていられない! ということでCanvasDirectorにUIを登録/削除すると各UIのSortingOrderを自動調整する機能を入れました。

 現在の自作プロジェクトではCamera.Depth・Canvas.SortingOrder・Hierarchyを使ってUIの前後関係を制御しています。UIの前後関係は以下の要素で決まります(Shaderは今回無視しています)。上の方が優先順位が高いです。

  • Canvas.RenderMode → UIは全部ScreenSpaceCameraモードにする予定(Overlayは使わない)
  • Camera.Depth → 使う
  • Canvas.SortingLayer → SortingOrderで頑張れば使わなくても良さそうなので何かのときのために取っておく
  • Canvas.SortingOrder → 使う
  • Hierarchy → 使う

 Hierarchyだけで制御するようにするとわかりやすいのですが、Canvasで適宜UIを分割した方がパフォーマンスが良くなるのでCanvasの設定を制御する必要がでてきました。

www.slideshare.net

 また、CameraのDepthはUI上で3Dオブジェクトを表示するために制御が必要です。3DオブジェクトはCanvasの制御を受けないので、表示の前後関係を操ろうとするならCameraの力を借りる必要があります。

SortingOrderの設定を覚えていられない

 通常UIは100、ヘッダーは200、ポップアップは300、ローディング表示は400と決めていくと、いずれ設定した箇所が多くなりすぎて覚えてられなくなります。設定をドキュメントに残しても、設定を増やしたときに更新されるとは限りません!

 また、UI内でParticleSystemを使っていると、このParticleSystemに設定してあるSortingOrderの管理も必要になります。何かの拍子にCanvasの設定を変更すると前後関係がメチャクチャになって地獄を見ます。

 さらに、そのParticleSystemよりも上にUIを表示したい、となるとUI内にさらにCanvas追加+OverrideSortingしてSortingOrderを設定する必要があり、手動で管理し切るのはなかなか難しい作業になります。

CanvasDirectorがSortingOrderを自動で管理するようにしよう

 Prefabに設定しておくと設定が散らばって収拾がつかなくなります。そこで、コード上に各UIの設定を記述して、その記述に従ってCanvasDirectorがSortingOrderを自動管理するようにしました。

 よくよく考えるとPrefabに持たせていた設定がコード側に来ただけなのですが、前後関係の変更・追加はかなり楽です。数値でなく列挙型で管理できるのもわかりやすさの向上につながっていると思います。例えば、現在のプロジェクトはFrontmost(エラー通知など最前面に出るUI)・Overlay(ローディング系)・Popup・Resident(ヘッダーなどの常駐UI)・Core(メインUI)・BackgroundというUI層を定義しています。

UI内のSortingOrderもある程度自動管理するようにしよう

qiita.com

のSortingOrderUpdaterの項に詳細を書きました。各UI・ParticleSystemのSortingOrderを相対値で設定しようというものです。UI内部のSortingOrderだけ気にすれば良いので、アプリ全体のSortingOrderを管理するよりかはだいぶマシになるはずです。