[Unity]NGUIのDepth設定その2(複数Atlas)
NGUI で複数の Atlas 利用時には、前後関係は Depth ではなく Z 座標で決まるというのは以前 [Unity]NGUIのDepth設定 に書いたのですが、これが結構くせがありました。
単一の Widget 同士なら単純に Z 座標が小さいほうが手前になりますが、複数の場合「同一 Atlas の Widget の Z 座標の平均値」が小さいほうの Widget 全てが、もう一方の全てより手前になるようです。
上図で、SciFi Label 1, 2 と Fantasy Label 1, 2 はそれぞれ同じ Atlas を利用しています。Fantasy Label 1 は Z=1 と 4 つの中で最も Z 座標が大きいですが、Fantasy Label 2 が Z=-3 であるため平均は Z=-1、一方の SciFi Label 1 と 2 の平均は (0 + -1)/2 = -0.5 となり、Fantasy Label 1 も SciFi Label 1, 2 より手前になっています。
普通は「手前 : Fantasy 2 > SciFi 2 > SciFi 1 > Fantasy 1 : 奥」を期待すると思うんですけどね。ちなみに、上の状態で DrawCall=2 です。
では、期待通りにするにはどうするかと言うと、一つは Panel の Depth Pass にチェックを入れることです。…が、アルファブレンディングが犠牲になる上に DrawCall=4 になるため、これは正直使わないと思います(そもそも用途が違いそう)。
結局、Panel を増やすことで、下図のような表示を得ることができました。DrawCall=3 です。
なお、ここでは Panel だけ Z 座標を順序付けし、Widget の Z は全て 0 にしています。実際の表示順序は各 Panel 配下の Widget の絶対 Z 座標の平均で決まるため、上図で Fantasy 1 の Z を -3 にしたり、Panel 1 にもう一つ Widget を追加して Z=-5 にすると、Fantasy 1 が一番手前になります。
NGUI のバージョンは v2.0.9a でした。
単一の Widget 同士なら単純に Z 座標が小さいほうが手前になりますが、複数の場合「同一 Atlas の Widget の Z 座標の平均値」が小さいほうの Widget 全てが、もう一方の全てより手前になるようです。
上図で、SciFi Label 1, 2 と Fantasy Label 1, 2 はそれぞれ同じ Atlas を利用しています。Fantasy Label 1 は Z=1 と 4 つの中で最も Z 座標が大きいですが、Fantasy Label 2 が Z=-3 であるため平均は Z=-1、一方の SciFi Label 1 と 2 の平均は (0 + -1)/2 = -0.5 となり、Fantasy Label 1 も SciFi Label 1, 2 より手前になっています。
普通は「手前 : Fantasy 2 > SciFi 2 > SciFi 1 > Fantasy 1 : 奥」を期待すると思うんですけどね。ちなみに、上の状態で DrawCall=2 です。
では、期待通りにするにはどうするかと言うと、一つは Panel の Depth Pass にチェックを入れることです。…が、アルファブレンディングが犠牲になる上に DrawCall=4 になるため、これは正直使わないと思います(そもそも用途が違いそう)。
結局、Panel を増やすことで、下図のような表示を得ることができました。DrawCall=3 です。
なお、ここでは Panel だけ Z 座標を順序付けし、Widget の Z は全て 0 にしています。実際の表示順序は各 Panel 配下の Widget の絶対 Z 座標の平均で決まるため、上図で Fantasy 1 の Z を -3 にしたり、Panel 1 にもう一つ Widget を追加して Z=-5 にすると、Fantasy 1 が一番手前になります。
NGUI のバージョンは v2.0.9a でした。
おまけ
検証中に、あるオブジェクト配下の全ての Widget の Z 座標を -Depth にするスクリプトを書きましたが、上記の挙動のためあまり役に立ちそうもありませんでした。一応貼っておきます。using UnityEngine; using System.Collections; [ExecuteInEditMode] public class OrderAdjuster : MonoBehaviour { void Update () { AdjustZ(transform); } void AdjustZ (Transform tf) { foreach (Transform child in tf) { UIWidget widget = child.GetComponent<UIWidget>(); if (widget) { child.localPosition = new Vector3( child.localPosition.x, child.localPosition.y, -(float)widget.depth); } else { AdjustZ(child); } } } }
コメント
コメントを投稿