Unityでモバイル向けのUIを設計していると、複数の画面(Canvas)を切り替える必要が頻繁に発生します。
たとえば「ホーム画面」「強化画面」「探索画面」「ガチャ画面」など、ゲーム内で遷移するUIが増えていく中で、1シーン内でそれらをどう整理・切り替えるかは設計上の大きなポイントです。
本記事では、筆者が現在開発中のゲーム内で採用している、「画面表示制御マネージャ(以下、CanvasManager)」の構成と実装例について紹介します。
なぜ専用マネージャが必要なのか?
- 複数Canvasを手動でアクティブ切り替えしているとスパゲッティコード化する
- 画面同士で排他的に表示したいが、制御がバラバラになりがち
- シーンを分けるほどでもないUIの遷移に手間をかけたくない
特にモバイルアプリでは「同一シーン内で完結」させたほうがパフォーマンスも管理もしやすいため、UI切り替えに特化したシンプルな仕組みが有効です。
Canvas構成の基本方針
- UIはすべて1シーンにまとめる(画面ごとにCanvasを分割)
- 各Canvasを空の親オブジェクトでまとめて管理
- 表示切り替えはすべてCanvasManagerから制御
- 表示Canvasは常に1つだけアクティブにする(他は非アクティブ)
CanvasRoot
├── HomeCanvas
├── UpgradeCanvas
├── ExploreCanvas
├── GachaCanvas
└── ...
実装例:CanvasManagerの構成
Canvasを切り替えるたびに、他のCanvasは必ず非アクティブにすることで、画面の重なりや想定外の挙動を防止します。以下にその具体例を示します:
public class CanvasManager : MonoBehaviour
{
[SerializeField] private List<GameObject> canvasList;
private GameObject currentCanvas;
public void ShowCanvas(string canvasName)
{
foreach (var canvas in canvasList)
{
if (canvas == null) continue;
bool isTarget = canvas.name == canvasName;
canvas.SetActive(isTarget);
if (isTarget)
{
currentCanvas = canvas;
}
}
}
public void ShowCanvas(GameObject targetCanvas)
{
foreach (var canvas in canvasList)
{
if (canvas == null) continue;
bool isTarget = canvas == targetCanvas;
canvas.SetActive(isTarget);
if (isTarget)
{
currentCanvas = canvas;
}
}
}
public GameObject GetCurrentCanvas()
{
return currentCanvas;
}
}
Inspector設定
canvasList
に対象の各Canvasオブジェクトを登録(手動でも自動でもOK)- 表示切替時は
CanvasManager.ShowCanvas("HomeCanvas")
などで呼び出し
補足:パフォーマンスと注意点
- 非表示Canvasは
SetActive(false)
で完全にオフになるため、不要なUpdate等は走らない - ただし、Update処理は走らせつつUIだけ切り替えたい場合、CanvasGroupでAlphaを0にし、RaycastTargetをオフにする構成も有効
// CanvasGroupを使った切り替え
CanvasGroup group = canvas.GetComponent<CanvasGroup>();
if (group != null)
{
group.alpha = isTarget ? 1f : 0f;
group.interactable = isTarget;
group.blocksRaycasts = isTarget;
}
- この方式では
SetActive(true)
のままにしておくことで、UpdateやCoroutineは維持される - アニメーションや状態保持をしたまま「シーン移行のようなUI表現」が可能になる
canvasList
の登録漏れや名前違いには要注意(enum化や定数化推奨)currentCanvas
を使えば「戻る」「履歴」などの実装にも応用可能
- 非表示Canvasは
SetActive(false)
で完全にオフになるため、不要なUpdate等は走らない canvasList
の登録漏れや名前違いには要注意(enum化や定数化推奨)currentCanvas
を使えば「戻る」「履歴」などの実装にも応用可能- CanvasのGraphicRaycasterとRaycastTarget設定も重要。非表示時には
GraphicRaycaster.enabled = false
にする- またはCanvas全体を
SetActive(false)
にしてRaycast自体を遮断
// 追加処理例:Raycast無効化
var raycaster = canvas.GetComponent<GraphicRaycaster>();
if (raycaster != null)
raycaster.enabled = isTarget;
こうすることで、「非表示UIが誤ってタップ判定を持つ」ような事故も防止できます。
- 非表示Canvasは
SetActive(false)
で完全にオフになるため、不要なUpdate等は走らない canvasList
の登録漏れや名前違いには要注意(enum化や定数化推奨)currentCanvas
を使えば「戻る」「履歴」などの実装にも応用可能
まとめ
1シーンで複数UI画面を切り替える場面では、**「専用のCanvas切り替えマネージャ」**を作ることで、
- スクリプトの責務分離
- UIフローの明確化
- バグ防止・パフォーマンス向上
など多くの利点があります。
ゲーム規模が大きくなる前に、こうしたマネージャの導入をぜひ検討してみてください。
ブログでもUnityや個人開発ネタを発信中です!
開発ノウハウやアプリ制作過程、Unity連携系のハマりポイントなど
より深掘りした内容をブログにまとめています。
▶ https://syunpp.com
公開中のアプリ一覧はこちら!
実際にUnityで開発してリリース済みのアプリ一覧をまとめています。
▶ https://syunpp.com/公開中のアプリ一覧/
YouTubeショートでもゲーム開発の裏側を公開中!
Unityで制作中のゲームの進捗や演出テスト、実装の様子を
ショート動画でタイムラプス形式にまとめて発信しています。
▶ https://www.youtube.com/@syunpp_8413/shorts
コメント