Unity(WebGL)で出力したゲームの解像度が環境によって変に表示された話
前置き
題名の通りですが、Unityで作成したゲームをWebGLで出力し、itch.ioと呼ばれるゲームの公開・販売プラットフォームにアップロードを行ったところ、次の2つのプレイ状態において、使用するPC環境により表示される画面の内容に違いが起きた。
- 通常時
- 全画面(フルスクリーン)時
そこでこの問題の謎に迫り、対処することにした。
はじめに結論
結論としては、GameObjectのうち、いくつかのuGUI要素(=Canvas要素)のもつCanvasScalerコンポーネントにしっかりと値が設定されていなかった。
問題発生時の環境
問題が発生した時、Unityのプロジェクトの内容は以下の状態であった。
プロジェクトの設定
- プロジェクトの採用しているバージョン:Unity2021.3.2f1
- プロジェクトの内容
- 2Dトップビュー的視点のゲーム
- キャラクターなどはGameObject
- マップなど、だいたいの背景はTileMap
- 最奥の背景、ステータスや進行状況などはUI(Canvas要素)で配置
- プロジェクトの解像度事情
- Gameパネル(デバッグ時)は"Full HD(1920✖️1080)"で確認
- 全てのCanvasコンポーネント
- RenderMode : "Screen Space - Camera"
- Project SettingのWeb GLにおける"Resolution and Presentation"設定
- Resolution
- Default Canvas Width : 960
- Default Canvas Height : 540
- WebGL Template
- Default
- Resolution
以上の内容で出力したものをitch.ioへアップロードした。
itch.io上で解像度に関係する項目は次のように設定し、ゲームの公開ページで、"Run game"ボタンをクリックすると、アップロードしたWebGLゲーム単体のみが表示されたWebページへ遷移し、ゲームが起動する設定にした。
検証環境
検証環境は以下のとおり、
環境 | 備考 |
---|---|
1. MacOS | ディスプレイサイズ:1440✖️900 Webブラウザ:Google Chrome |
2. Windows11 | ディスプレイサイズ:1920✖️1080 Webブラウザ:Google Chrome |
問題内容
Full HD(1920✖️1080)仕様で制作していたものをWebGL用に960✖️540(ゲーム制作時の半分)サイズの枠に納めて動作する様に出力した後、次の2環境で異なる表示結果になった。
1.MacOS上でのトラブル
Build結果をアップロード後、
- 通常時:問題なし
- 全画面時:UIの表示が崩れた
2.Windows上でのトラブル
Build結果をアップロード後、
- 通常時:UIの表示が想定の倍サイズになっており、枠(960✖️540)をはみ出している。枠を超える部分は表示されない
- 全画面時:問題なし
1の状態時の表示例は次のとおり、右上基準で配置したUIは枠の右上基準で大きく表示されている
解決に至った背景
通常のGameObject(World配置)やTileMapは通常時とフルスクリーン時とで解像度を変えてもきちんと大きさの変更が行われ、表示に問題はなかった。このため、 UIに問題があることがわかった。
またラッキーなことに、今回編集していたプロジェクトは複数シーンで構成されたゲームであり、UIに異常の起きていないシーンが存在していることが判明。問題ないシーンと問題あるシーンを比べることで解決が早まった。
以上を踏まえて、幾らかの操作やパラメータの変更を行なうことで、原因特定に至る。
- Unity Editor上でGameパネルの解像度を変更するなどして、見た目がどのように変化するかチェック
- 1920✖️1080や960✖️540がどこから参照され、どこに影響しているかを調査
- Project Settings
- Main Camera ゲームオブジェクト
- ルートCanvas ゲームオブジェクト
- Canvas コンポーネント
- Canvas Scaler コンポーネント
対策
各ルートCanvasの持つ、Canvas Scalerコンポーネントの設定を次のように変更。
- UI Scale Mode : Scale with Screen Size
- Reference Resolution
- X : 1920
- Y : 1080
また、Prefabで編集→展開利用していたCanvas要素はUnity Editor上では"Non-root Canvases will be not scaled"と警告され、値を直接いじることができなかったため、Instantiateした直後に参照を取得し、強制的に値を変更した。以下はプログラムサンプル。
CanvasScaler hogeCanvasScaler = hogeCanvas.gameObject.GetComponent<CanvasScaler>();
hogeCanvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
hogeCanvasScaler.referenceResolution = new Vector2(1920, 1080);
後書き
よくある、Canvas Scaler設定のミス、設定忘れだった。
もし世界のどこかで同じ状況が発生した方がいらっしゃった場合に、参考になれば嬉しいです。
Discussion