UIキャンバス(uGUI)の頻繁な再ビルド(Rebuild)による処理落ちの回避策は、実機テストやレンダリングパイプライン拡張において頻発する重度なテクニカルバグです。UIのテキストやアイコンを動的に更新した際に、Canvas全体のメッシュ再構築(Rebuild)が発生してCPUがスパイクする負荷の解決策の解説。
不具合の具体的な症状
ゲーム内でプレイヤーのHPバーが動いたり、画面上の制限時間タイマーが1秒ごとに更新されるたびに、ProfilerのCPU Usageに巨大なスパイク(トゲ)が発生し、一瞬画面が詰まるようにカクつく。
現実世界での例え:クラスの1人のテストの点数(タイマー)が書き換わるたびに、クラス全員の名簿と顔写真(Canvas全体)を1からすべてカメラで撮り直す超非効率な事務作業
1つの同じ巨大な黒板(Canvas)に全員の似顔絵を描いており、1人の前髪を少し消しゴムで消して直す(タイマー更新)たびに、黒板全体の全員の似顔絵をすべて消しゴムで消して最初から全員分を精密に描き直している非常に理不尽な状態です。動く人(タイマー)だけを別の小さなスケッチブック(サブCanvas)に分けて描いておくことで、描き直しの手間をスケッチブックの1枚の小さな落書きだけに抑え込みます。
図:UIキャンバス(uGUI)の頻繁な再ビルド(Rebuild)による処理落ちの回避策の不具合発生メカニズムと解決アプローチの概要図
想定される原因と詳細な仕組み
uGUIの仕様上、同じCanvas内にあるUI要素(テキストや画像)が1つでも変形・書き換えられると、そのCanvasに属する「すべてのUI要素」のメッシュ(頂点データ)を1つの巨大な複合メッシュとしてCPU側で丸ごとゼロから再計算して再構築(Canvas.SendWillRenderCanvases)するためです。
解決アプローチと最適化手順
常に激しく値が書き換わる動的なUI要素(タイマーやHPバーなど)を、背景の動かない静的なUI(メニュー外枠や背景画像など)とは「別のサブCanvas(Sub Canvas)」として親子関係のまま独立させ、再構築の影響範囲を極小のUIパーツ内だけに封じ込めます。