UnityのUIをAndroid実機で確認したら崩れていた問題と修正方針
Unityで制作中のおはじきバトルをAndroid実機で確認したところ、UIの重なり、タブアイコンの欠け、スクロール方向の違和感が見つかりました。現時点で確認できた事象と、uGUI・Prefabへ移行して修正する方針をまとめます。
Unityで制作中のスマートフォン向けゲーム「おはじきバトル」では、ホーム画面のUIを作り直しています。
Unity上で画面を確認した段階では、大きな問題はないように見えていました。しかし、Android端末へビルドして実際に操作すると、PC上の確認だけでは気づかなかった問題が複数見つかりました。
今回確認できた主な問題は、次の3点です。
- クエストカードがスタミナなどの上部表示の裏へ入り込む
- 下部タブアイコンの縁が切れる
- スクロールが指の動きと反対に感じられる
現在はまだ修正途中です。
この記事では、解決済みの手順としてではなく、実機で確認できた事象、考えられる原因、これから実施する修正方針を記録します。

Android実機で確認したホーム画面。クエストカードが上部表示の裏へ入り込み、下部タブアイコンの縁も一部切れています。
Unity上の確認だけでは分からなかった
開発中は、UnityのGameビューを使って画面を確認していました。
Gameビューでは、設定した解像度に合わせてUIが表示されます。しかし、実際のAndroid端末には、画面の縦横比、ステータスバー、ナビゲーション領域、ノッチなど、端末ごとの差があります。
また、マウスで操作したときと、指で直接スクロールしたときでは、操作感の受け取り方も異なります。
今回の確認から、UIは「Unity上で崩れていない」だけでは不十分で、実機での表示と操作を早い段階から確認する必要があると分かりました。
問題1:クエストカードが上部表示の裏へ入り込む
Android端末でホーム画面を開くと、スクロール領域にあるクエストカードが、スタミナやゴールドなどを表示する上部領域の裏側に見えていました。
クエストカードそのものは表示されていますが、本来は上部バーより下に収まるべき内容が、スクロールした際に上まで入り込んでいます。
考えられる原因
現時点では、次の点を確認する予定です。
- スクロール領域のViewportが上部バーまで広がっている
- ViewportにMaskまたはRectMask2Dが設定されていない
- ContentのアンカーやPivotが画面サイズに合っていない
- 上部バーとスクロール領域の表示順だけで隠している
- Safe Areaを考慮せず、画面全体を基準に配置している
上部バーを最前面へ表示するだけでも見た目は隠せます。しかし、スクロール可能な範囲そのものが誤っている場合、別の端末で再び問題が起きる可能性があります。
そのため、表示順だけではなく、Viewportの範囲とクリッピング設定を確認する方針です。
修正方針
ホーム画面を次の領域へ分けます。
Safe Area
├─ Header:ランク・スタミナ・ゴールド
├─ Content Area:クエストカードなどのスクロール領域
└─ Bottom Navigation:下部タブ
スクロール領域は、Headerの下からBottom Navigationの上までに限定します。
Viewportには RectMask2D を設定し、領域外へ移動したカードが表示されないようにします。
問題2:下部タブアイコンの縁が切れる
ホーム、キャラ、クエスト、編成、設定のタブアイコンは、Unity上では枠を含めて表示されていました。
しかしAndroid端末では、アイコンの外側にある縁の一部が切れて見えました。
考えられる原因
この問題には、複数の原因が考えられます。
- 元のPNG画像で、絵柄と画像端の余白が少ない
- ImageのRectTransformがアイコンより小さい
- 親オブジェクトのMaskによって外側が切られている
- Preserve Aspectの設定と領域サイズが合っていない
- Canvas Scalerによる縮小で、細い縁が見えにくくなっている
- 下部のシステムナビゲーション領域と重なっている
まずは、元画像の透明な余白と、Unity上のRectTransformを分けて確認します。
元画像に余白がなければUnity側で領域を広げても縁は復元できません。一方、画像に余白がある場合は、親オブジェクトやMaskの影響を確認します。
修正方針
すべてのタブアイコンについて、次の条件をそろえます。
- PNGのキャンバスサイズ
- アイコンの中心位置
- 外側の透明な余白
- RectTransformの幅と高さ
- 親オブジェクト内でのアンカー
さらに、下部ナビゲーション全体をSafe Area内に配置し、端末のナビゲーション領域と重ならないようにします。
問題3:スクロール方向に違和感がある
実機で画面を指で動かしたところ、表示内容が指の動きと反対へ移動しているように感じました。
マウスやエディター上の確認では気づきにくく、指で直接触ったことで違和感が明確になりました。
確認する項目
スクロール処理について、次の点を確認します。
- Unity標準の
ScrollRectを使用しているか - ドラッグ量の符号を独自処理で反転していないか
- Contentの位置をコードで更新していないか
- 縦スクロールと横スクロールの設定が正しいか
- 慣性や移動量が過剰になっていないか
独自のドラッグ処理で座標を更新している場合は、入力された移動量とContentへ加える値の向きが一致しているか確認します。
今後は、可能であればUnity標準の ScrollRect を基準にし、独自処理は必要な範囲だけに限定する方針です。
時計や通知の領域はどう扱うか
Android端末の上部には、時刻、通知、電池残量などを表示するステータスバーがあります。下部には、端末によってナビゲーションバーやジェスチャー操作用の領域があります。
ゲームを全画面表示にする場合と、システムバーを残す場合では、利用できる表示範囲が異なります。
今回のUI修正では、最初に次の方針を決める必要があります。
- 常に全画面表示にする
- ステータスバーを表示した状態で使用する
- 状況によって表示と非表示を切り替える
方針を決めずにUIだけを調整すると、システムバーの設定を変更した際に再び画面がずれる可能性があります。
まずは実機で最終的に使用する表示方法を決め、その状態でSafe Areaを取得してUIを配置する予定です。
Canvas Scalerを見直す
異なる画面サイズへ対応するため、Canvas Scalerの設定を確認します。
基本となる候補は次の設定です。
UI Scale Mode: Scale With Screen Size
Reference Resolution: 基準とする縦画面の解像度
Screen Match Mode: Match Width Or Height
Match の値を幅と高さのどちらへ寄せるかによって、縦長端末での余白やUIの大きさが変化します。
設定値だけを決めるのではなく、少なくとも次の画面比率で確認します。
- 基準にしているAndroid端末
- 縦長の端末
- 横幅が比較的狭い端末
- Unity Gameビューの複数解像度
画面全体を一律に拡大縮小するのではなく、上部、中央、下部それぞれのアンカーも合わせて設定します。
コードで生成するUIの問題
現在のUIは、コードによって実行時に生成される部分が多くあります。
この方法は、同じ構造を自動で作れる一方、Unityを停止している状態では完成形をSceneビューで確認しにくいという問題がありました。
位置や大きさを少し直す場合でも、次の手順が必要になります。
- コードの数値を変更する
- Playモードで画面を生成する
- 表示を確認する
- Playモードを停止する
- 再びコードを修正する
細かな余白やアイコンサイズの調整を繰り返すには時間がかかります。
また、Playモード中にInspectorで変更した値は、停止すると元へ戻るため、調整結果を残し忘れる可能性もあります。
uGUIとPrefabへ移行する方針
細かなUI調整をしやすくするため、ホーム画面を uGUI + Prefab を中心とした構成へ移行する予定です。
SceneまたはPrefab上にUIの構造を作り、コードは表示内容や状態の変更を担当します。
見た目と配置
→ Canvas、RectTransform、Image、Text、Prefab
データと動作
→ C#スクリプト
例えば、スタミナの枠やアイコンの位置はPrefab側で調整し、現在値や回復時間はスクリプトから反映します。
この分け方により、見た目の変更だけであればSceneビューとInspectorを使って調整しやすくなります。
移行予定の順番
一度にすべてを作り直すのではなく、次の順番で進めます。
- 現在のホーム画面を保存し、比較できる状態にする
- CanvasとCanvas Scalerを作成する
- Safe Area用の親オブジェクトを作成する
- HeaderをPrefab化する
- Bottom NavigationをPrefab化する
- 中央のScrollRectとViewportを作成する
- クエストカードをPrefab化する
- スクリプトから表示データを反映する
- PCとAndroid実機で比較する
まず外側のレイアウトを決めてから、中にカードやボタンを配置します。
先に個別要素から作ると、全体の高さが足りなくなったときに調整範囲が広がるためです。
移行時に残すもの
uGUIとPrefabへ移行しても、現在のコードをすべて捨てるわけではありません。
次のような処理は、引き続きスクリプトが担当します。
- スタミナとゴールドの現在値を表示する
- ランク経験値ゲージを更新する
- クエスト情報をカードへ反映する
- ボタンを押したときに画面を切り替える
- 選択中のタブ表示を変更する
- セーブデータを読み込む
変更するのは、主にUIオブジェクトを作る方法と配置方法です。
見た目をPrefab、値と動作をスクリプトへ分けることを目標にします。
修正後に確認する項目
移行後は、見た目だけでなく操作も含めて再確認します。
- クエストカードがHeaderの裏へ表示されない
- スクロール領域がHeaderとBottom Navigationの間に収まる
- タブアイコンの縁が切れない
- 指の動きに対して自然にスクロールする
- 上端と下端でスクロールが不自然に飛ばない
- Androidの戻る操作で画面遷移が崩れない
- 端末のステータスバーやナビゲーション領域と重ならない
- 異なる縦横比でも主要なボタンが押せる
- Playモードを開始しなくてもUIの配置を確認できる
修正前と修正後を同じAndroid端末で撮影し、違いを比較する予定です。
まとめ
Unity上では問題なく見えていたホーム画面も、Android実機で確認すると、UIの重なり、アイコンの欠け、スクロール方向の違和感が見つかりました。
現在は原因を断定して修正を終えた段階ではありません。
まずCanvas Scaler、Safe Area、アンカー、Viewport、Mask、ScrollRectを確認し、細かな調整をしやすくするために、コード生成中心のUIからuGUIとPrefab中心の構成へ移行する方針です。
次回は、実際に移行した手順、変更した構造、Android実機での再確認結果を記録する予定です。