太郎Work

Unityとかで困ったこと等を残しておきます

NGUIではないオブジェクトをNGUIの手前に描画するスクリプト作ってみた

以前の投稿で

NGUIではないオブジェクトをNGUIの手前に描画する方法 - 太郎Work

このような記事を書きましたが、ParticleSystemやメッシュを手前に持ってきたい場合や任意の場所に挟みたい場合は非常にめんどうでした。

やはりNGUIのdepthで管理したくなったのでコンポーネントを作成しました。

注意!:NGUI3.x用です
tarob19/UIUnityRenderer · GitHub

実行例

後ろからdepth0, depth2, depth4で指定したUITextureにParticleSystemを入れた場合の実行結果です
直感的に任意のレイヤーにParticleが表示できているのがわかると思います。
コンポーネントに最終的なRenderQueueの確認もできるようにしました。
もちろんNGUIのDrawCallToolでも見られます。

f:id:tarowork:20140608214334p:plain
depth = -1 一番裏側

f:id:tarowork:20140608214438p:plain
depth = 1

f:id:tarowork:20140608214505p:plain
depth = 3

f:id:tarowork:20140608214532p:plain
depth = 5 最前面

ParticleSystemと同じGameObjectにアタッチしてUIPanel以下に入れるとUIWidgetのdepthで管理できるようになります。
使いたい方はどうぞ。ただし使ったことによる責任は一切負えません

以下詳細

GetComponentでRendererを取得してNGUIにWidgetとして登録しています。

OnFillで画面外にダミーのメッシュ情報をセットしておくことで、かならず1drawCall発生するようにしています。
ただし、画面外に描画されるためUnityの方でカリングされるので無駄なDrawCallは発生せずRendererのDrawCallのみなのでご安心下さい。

depthを操作するとUIDrawCallが書き換わるのでその値をコピーしたMaterialにセットしています。

しかし、デフォルトではこれは実行時のみ適用するようにしています。
これは、SharedMaterialを書き換えるとProjectのマテリアル情報が随時書き換わるためバージョン管理をしている場合UIPanelを操作する度に変更点として上がってしまうためです。

そんなことは気にしないor実行前に確認したいという方はUseSharedMaterialにチェックを入れるとRendererのマテリアルを直接操作するようになります。

とりあえず複数マテリアルに対応しましたが本当に動くかは分かりません。
UIWidgetのmPlayModeがうまく取れなかったので毎フレームチェックになってしまいました。。。

試行錯誤で結構苦労したけど最終的に良い感じになってよかった。