確認環境
- UE4.24.3
まえがき
突然ですが、下のスクショを見てください。WidgetのUIパーツが重なった状態です。(ZOrderはすべて0になっています。)
なんかWidgetの表示がおかしいです...
確認を込めて表示順について説明しておきますと、Canvas Panelの子パーツは階層パネルの上から順番に表示されていきます。したがって、階層パネルで下にあるパーツほど手前に表示されるようになります。
ですが、このスクショではBorderが階層パネルの一番下にある(=一番手前に表示される)はずなのに他のパーツより奥に表示されています。よく見てみるとBorderとSliderの重なり方もなんかおかしいです。
この記事ではこのように階層順と表示順がちぐはぐな状態になったときの原因と対応を書いていきます。
原因
表示がおかしい原因は簡単で、「パーツの表示順をZOrderで決めて、階層順を無視する設定」がオンになっていたからです。
この設定、"Explicit Canvas Child ZOrder"という名前で設定場所は↓にあります。
[プロジェクト設定] > [エンジン] > [スレート設定] > [Constraint Canvas] > [Explicit Canvas Child ZOrder]
"Explicit Canvas Child ZOrder"について
この設定は「ZOrderが同一のものはまとめて描画しよう」というもので、オンにするとドローコールを抑えることができ描画負荷を軽減することができます。
ちなみに、この設定はパネルの性質の関係でCanvas Panelの子パーツにだけ作用するようです。(他のパネルの子パーツだとZOrderの設定がないです)
対応
冒頭の表示問題の対応は2つあります。
- "Explicit Canvas Child ZOrder"をオフにする。
- 個々のパーツにZOrderを設定する。
1番の方法で対応するとこんな感じになります。 ちゃんと階層順で表示されるようになりました。もちろん、パーツにZOrderが設定されていればそちらが優先されます。
ただ、デスクトップ / コンソール向けに開発している場合はどちらで対応してもいいのですが、モバイル / タブレット向けに開発している場合は描画負荷を抑えるために2番の対応がいいかなと思います。
いつそんな設定したっけ?
自分はこの症状が出た時、「いつそんな設定をしたかな?」と思っていました。実はこれターゲットハードウェアをモバイル / タブレットにすると設定がオンになるのです。
気づいていませんでした...
モバイル / タブレットでの負荷を抑えるため、UE4が気を利かせています。ここはUE4に甘えて、よっぽどのことがない限りオンのままにしておきましょう。
参考資料
あとがき
結局のところ、前後の見た目おかしいならZOrder設定すれば解決する話でした。が、原因を知っておくともうつまずくことはないかと思います。
ただ、"Explicit Canvas Child ZOrder"なんて設定も知らなかったし、検索しようにも検索ワードが思いつかず苦戦しました。
いつか「UE4 Widget 表示順 おかしい」なんて検索ワードで、この記事がヒットして誰かの進捗アップにつながればいいなと思っています。