sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

Unity 2D ゲームの画面(メインカメラ)サイズの選択と設定例

この記事の内容は「Unity blog - 2D アートアセットの解像度選択」の内容を参考にしてゲームの画面サイズをどのように決めて、どのように設定するのか、その一例を記録したものです。

2022 年 5 月加筆
2Dで好まれる Canvas を利用したパターンの記事「Unity「2D game art, animation, and lighting for artists」を日本語で読む」を書きました。Unity 公式が 2D クリエイター向けに公開した中にカメラの設定が含まれています。英語の資料なので、和訳を進めています。

2020 年 8 月加筆
2Dで好まれる Canvas を利用したパターンの記事「Unity Canvas を使った2Dゲーム画面設計と Reference Resolution のプラクティス」を書きました。使い分けしていただけると幸いです。使い分けの参考記事は Unity スマートフォン(複雑なアスペクト比)対応とレスポンシブ UI の基本 になります。


概要・基本的な考え方

まず、この記事の大筋として2Dゲームにおける画面の考え方は、次を参考にするとベターだと考えています。

2D ではスケールの問題の重要性は下がりますが、プロジェクトで物理演算を使う場合は、やはりスケールのことを考慮するほうがいいでしょう。Tilemap を使っている場合は、シンプルに取り回せるように、1 タイル = 1 ユニットになるようスケールを設定するのがいいでしょう。
- Unity Blog - Unity シーン内での計測より

Unity で使われる単位は px (ピクセル)ではなく「ユニット」と呼ばれる単位(距離、サイズを表現するもの)です。

なので、「2D ゲームの画面(メインカメラ)サイズの選択」という問題は、縦と横はどういった「ユニット」比になるのか、という話にも置き換えつつ、話を進めていきます。


例:どういったゲーム画面を考えるのか?

今回は、Game Boy 版のテトリスの画面サイズを考えることにしました。

ゲームボーイ版「テトリス

テトリスのブロック操作部の仕様 (Dimension) は次のとおり。(1マス=1ブロック)

  • 縦 18 マス
  • 横 10 マス

ブロックは、次を作成・使用しました。画像サイズは (20x20) です。これがユニットのサイズの基本にしようと思います。

ブロック素材

言い換えておくと、ユニット比だと 10x18 をサポートすることが目安になりそうです。(横に10ユニット、縦に18ユニット配置できること)

さて、ゲーム画面の構想ができたので、画像をインポートして設定をはじめてみます。


設定

画像のインポート

Unity は、画像をインポートしたとき、画像は Pixels per Unit (PPU) というパラメーターを持つ Assets(素材) として扱われます。

PPU は、Unity シーンの 1 ユニットの中に収められるピクセルの数を表しています。1

ブロックの素材は、元の画像サイズの pixel 数にあわせて PPU を「20」に設定します。(1ユニットに収めるピクセル数だから)

素材の設定例

  • ブロックの Pixels Per Unit を 20 に設定
  • ブロックの Filter Mode を Point (no filter) に設定

画面のアスペクト比

参考にしたゲームボーイ (GB) の画面サイズは、160 x 144 なので比率は 10:9 です。ここでは、近い比率の 5:4 を選択してみます。補足として、Full HD の場合は、1280 x 720 など。これは 16:9 です。(比率計算用リンク

想定される最大の解像度を選び、プロジェクト全体での指標に設定するべきであるということです。チームメンバーはその指標に基づいてアセットの製作における決定を下せます。
- Unity Blog - プラットフォームに合わせた解像度を指定するより

メインカメラ (Main Camera) の設定

  • ProjectionOrthographic に設定 2
  • Size9 に設定

縦ユニット数の半分

Projection の設定値を Orthographic に設定したときのプロパティ、Size の値「9」は、画面の縦半分に Unit がいくつ入るのかを指定しています。

今回の仕様では、縦18ブロックなので、半分の「9」になります。 ただし、Size の設定は、後述のキャンバスのレンダリングScreen Space であれば Canvas Scaler の設定を優先するように思います。Size の設定は「0」でもない限り、あまり気にする必要がない。(自動的に Scale を調整してくれるから)


キャンバス (Canvas) の設定 (Screen Space 編)

キャンバスの Render Mode の設定で、このあとの描画方法が大きく異なることになります3

Render Mode のオプションは次のとおり。詳細は「マニュアル」を参照。

  • Screen Space
    主に Canvas Scaler といった画面サイズ設定に依存する UI 用のスクリーン空間
  • World Space
    (X, Y, Z) で表される通常の 3D 空間

2D ゲームにおいては、 Screen Space でも World Space でも、好みくらいの話で、どちらでも問題なく作ることができそうです。

ただ、uGUI を利用したほうが楽できることは多そうなので、利用する方向から考えると完成がはやそう。Canvas を利用した設計 は必ず検討したほうがよいと思います。

World Space は自由度が高く Unit の設定が重要になります。Screen Space は、キャンバスのサイズがカメラサイズになり、キャンバスに追加されるプロパティ Canvas Scaler で制御するのが楽ではないかと思います。

Screen Space を利用するとして、話をすすめます。Canvas Scaler の設定値はざっくり次のとおり。詳細は「マニュアル」。

  • Constant Pixel Size
    ピクセルを基準に GUI のサイズを決定
  • Scale With Screen Size
    指定した画面サイズを基準に GUI を拡大・縮小する
  • Constant Physical Size
    物理的単位 (mm, cm, inch...) を基準に UI のサイズを決定

今回は、縦方向のブロック数=高さがわかっています。PPU = 20 のブロックを 縦に 18 個積むので高さは 360 です。横幅は 5:4アスペクト比率を予定しているので 450 です。

というわけで、指定した画面サイズを基準にできそうなので、Scale With Screen Size の設定値を使ってみることにします。

設定が多いので注意&値の意味を理解しよう

  • CanvasRender ModeScreen Space に設定
  • Canvas ScalerUI Scale ModeScale With Screen Size に設定
  • Canvas ScalerReference ResolutionX:450, Y=360 に設定
  • Canvas ScalerMatchHeight:1 に設定
  • Canvas ScalerReference Pixel Per Unit20 に設定

イメージの配置

キャンバス内に uGUI から image を追加して、インポートしたブロックの素材を Source Image に設定します。

ここでも大きさを設定。関連を整理する。

  • Rect TransformWidth20 に設定
  • Rect TransformHeight20 に設定
  • Pos XPos Y(0, -10) に設定

Pos はイメージの中心を基点と(現在)しているため 20 x 20 の画像だと Pos は 10 ズレて (0, -10) にする。x 座標の位置はあとで調整するんで、とりあえずの「0」。

縦方向に18個のブロックを並べて、2列にすると下図のようになります。

わりと予定通りの画面が作れた!

それらしいウィンドウやテキストなんかを追加することで、基本画面の完成。落ちてくるブロックの描画範囲もわかりやすいですね。

このような感じで、画面のアスペクト比率を設定して、ブロックのサイズを決めて、見立てどおりに画面サイズの選択と設定ができたと思います。

キャンバス (Canvas) の設定 (World Space 編)

おまけとして、World Space 座標系だとどうなるか。

  • CanvasRender ModeWorld Space に設定
  • CanvasEvent CameraMain Camera に設定

レンダリングWorld Space の場合は、Screen Space とは違って Scale With Screen Size のような UI 用のスクリーン座標に変換するといったことをしません。

2D Object から Sprite を追加します。SpriteTransform で位置を設定してください。(Height, Width を持たないだけで同じこと)

sprite の設定はこんな感じに

uGUI の Image と Sprite の使い分けは「テラシュールブログ - uGUIのImageとSprite Rendererの使い分け」などを参考に。

  • SpriteTransformPosition を設定

親子関係のよいポイントとして、親に Empty を追加して、親の位置を padding として扱えば、簡単に始点の位置を調整できます。

座標系の調整

こちらの場合でも、カメラに設定した OrthographicSize に対応して、シンプルに配置ができました。基本的なアスペクト比 5:4 を維持できる限り、この設定でも十分使えそうです。


応用のための学習

環境のアスペクト比が一定しないスマートフォンなどに対応する場合の Tips は、次の記事でまとめました。

サンプル

自分が作成したテトリスのプログラムを GitHub に公開しています。カメラの設定やサイズを考えるキッカケになったプログラムで、一応ブロックを消して遊べます。

はじめて Unity のゲームを作ったプログラムなので、最適化できていなかったり、画面サイズも考慮せずに(できずに)作ってます。(横12マスじゃなくて10とのご指摘が入ったりも)

3日で作れました

おまけのおまけで、Screen Space の設定でテトリスのブロックを配置しただけのプロジェクト。

参考


  1. ゲームオブジェクトのスケールが (x:1, y:1, z:1) に設定された場合

  2. 詳細は「マニュアル」を参照する

  3. これも詳細は、調べておくとよい