複数の解像度

複数の解像度の問題

開発者は、ゲームで複数の解像度を最適にサポートする方法を理解するのに苦労することがよくあります。デスクトップおよびコンソールゲームの場合、ほとんどの画面アスペクト比は16:9であり、解像度は標準化(720p、1080p、1440p、4Kなど)されているので、多かれ少なかれこれは簡単です。

モバイルゲームの場合、最初は簡単でした。長年、iPhoneとiPadは同じ解像度を使用していました。そして Retina を実装すると、ピクセル密度が2倍になりました。ほとんどの開発者は、デフォルトおよび二重解像度でアセットを提供する必要がありました。

現在では、さまざまな画面サイズ、密度、アスペクト比が存在するため、これはもはや当てはまりません。超ワイドディスプレイなど、従来とは異なるサイズも人気が高まっています。

3Dゲームの場合、(美的観点から)複数の解像度をサポートする必要はあまりありません。 3Dジオメトリは、アスペクト比を無視して、視野に基づいて画面いっぱいに表示されます。これをサポートしたい主な理由は、この場合、パフォーマンスが理由(1秒あたりのフレーム数を増やすために低解像度で実行するため)です。

2DおよびゲームUIでは、Photoshop、GIMP、Kritaなどのソフトウェアで特定のピクセルサイズを使用してアートを作成する必要があるため、これは別の問題です。

レイアウト、アスペクト比、解像度、ピクセル密度は大きく変化する可能性があるため、特定の画面ごとにUIを設計することはできなくなりました。別の方法を使用する必要があります。

ワンサイズですべてに対応

最も一般的なアプローチは、単一の base 解像度を使用し、それを他のすべてに適合させることです。この解像度は、ほとんどのプレイヤーがこれでゲームをプレイすることが期待されます(特定のハードウェアが与えられた場合)。モバイルの場合、Googleには便利な stats があり、デスクトップの場合、Steamには https://store.steampowered.com/hwsurvey/ もあります。

例として、Steamは最も一般的な プライマリディスプレイ解像度 が1920×1080であることを示しているため、賢明なアプローチはこの解像度のゲームを開発し、異なるサイズとアスペクト比にスケーリング処理をすることです。

Godot provides several useful tools to do this easily.

ベースサイズ

ウィンドウの基本サイズは、[プロジェクト設定]の Display → Window で指定できます。

../../_images/screenres.png

ただし、それが何をするのかは完全には明らかではありません。エンジンは、モニターをこの解像度に切り替えようとはしません。むしろ、この設定を「設計サイズ」、つまりエディタで作業する領域のサイズと考えてください。この設定は、2Dエディタの青い長方形のサイズに直接対応しています。

多くの場合、画面とウィンドウのサイズがこの基本サイズと異なるデバイスをサポートする必要があります。Godotには、さまざまな画面サイズに合わせてビューポートのサイズを変更および拡大する方法を制御する多くの方法があります。

サイズ変更

デバイスにはいくつかのタイプがあり、いくつかのタイプの画面があり、それらは異なるピクセル密度と解像度を持っています。それらすべてを処理するのは大変な作業になる可能性があるため、Godotは開発者の生活を少し楽にするように努めています。 Viewport ノードにはサイズ変更を処理するいくつかの関数があり、シーンツリーのルートノードは常にビューポートです(読み込まれたシーンはその子としてインスタンス化され、get_tree().get_root() または get_node("/root") を呼び出すことでいつでもアクセスできます)。

いずれにせよ、ルートビューポートのパラメーターを変更することが問題に対処するためのおそらく最も柔軟な方法ですが、多くの作業、コード、推測が必要になる可能性があるため、Godotは複数の解像度を処理するためにプロジェクト設定でパラメーターのシンプルなセットを提供します。

ストレッチ設定

Stretch settings are located in the project settings and provide several options:

../../_images/stretchsettings.png

ストレッチモード(Stretch Mode)

Stretch Mode 設定は、ウィンドウまたは画面の解像度に合わせてベースサイズを拡大する方法を定義します。

../../_images/stretch.png

以下のアニメーションでは、さまざまなストレッチモードの効果を示すために、わずか16×9ピクセルの「ベースサイズ」を使用しています。同じくサイズが16×9ピクセルの単一のスプライトがビューポート全体をカバーし、その上に対角線 Line2D が追加されます:

../../_images/stretch_demo_scene.png
  • Stretch Mode = Disabled (デフォルト): ストレッチは行われません。シーン内の1単位は、画面上の1ピクセルに対応します。このモードでは、Stretch Aspect 設定は効果がありません。

    これは、すべての画面ピクセルを完全に制御する場合に適したオプションであり、おそらく3Dゲームに最適なオプションです。

    ../../_images/stretch_disabled_expand.gif
  • Stretch Mode = 2D: このモードでは、プロジェクト設定の display/width および display/height で指定されたサイズが、画面全体をカバーするようにストレッチされます(Stretch Aspect 設定を考慮に入れて)。これは、すべてがターゲット解像度で直接レンダリングされることを意味します。 3Dはほとんど影響を受けませんが、2Dでは、スプライトピクセルとスクリーンピクセルが1対1で対応しなくなり、スケーリングのアーティファクトが発生する可能性があります。

    これは、2Dアートワークの解像度が十分に高く、ピクセル対ピクセルのレンダリングを必要としない場合に適したオプションです。 2Dテクスチャとフォントのテクスチャフィルタリングとミップマッピングを有効にすることを検討してください。

    ../../_images/stretch_2d_expand.gif
  • Stretch Mode = Viewport: ビューポートのスケーリングは、ルート Viewport のサイズがプロジェクト設定の Display セクションで指定されたベースサイズに正確に設定されることを意味します。シーンは最初にこのビューポートにレンダリングされます。最後に、このビューポートは画面に収まるように拡大縮小されます(Stretch Aspect 設定を考慮に入れて)。

    このモードは、ドット絵のゲームで作業する場合、またはパフォーマンスを改善するために低解像度にレンダリングするために役立ちます。

    ../../_images/stretch_viewport_expand.gif

ストレッチアスペクト(Stretch Aspect)

2番目の設定は Stretch Aspect です。これは、Stretch ModeDisable 以外に設定されている場合にのみ有効であることに注意してください。

以下のアニメーションでは、灰色と黒の領域に気づくでしょう。黒い領域はエンジンによって追加され、描画できません。灰色の領域はシーンの一部であり、描画できます。灰色の領域は、2Dエディタに表示される青いフレームの外側の領域に対応しています。

  • Stretch Aspect = Ignore: 画面をストレッチするときにアスペクト比を無視します。これは、幅が広くても狭くても、元の解像度が拡大されて画面全体に表示されることを意味します。これにより、不均一なストレッチが発生する可能性があります。物体が設計よりも幅が広い、または背が高く見えます。

    ../../_images/stretch_viewport_ignore.gif
  • Stretch Aspect = Keep: 画面をストレッチするときにアスペクト比を維持します。つまり、ビューポートは画面の解像度に関係なく元のサイズを保持し、画面の上部/下部(「レターボックス化」)または側面(「ピラーボックス化」)に黒いバーが追加されます。

    これは、ターゲットデバイスのアスペクト比を事前に知っている場合、または異なるアスペクト比を処理したくない場合に適したオプションです。

    ../../_images/stretch_viewport_keep.gif
  • Stretch Aspect = Keep Width: 画面をストレッチするときにアスペクト比を維持します。画面が基本サイズよりも広い場合、黒いバーが左右に追加されます(ピラーボックス化)。ただし、画面が基本解像度よりも高い場合、ビューポートは垂直方向に拡大されます(そして、より多くのコンテンツが下部に表示されます)。これを「垂直方向に拡張」と考えることもできます。

    これは通常、スケーリングするGUIまたはHUDを作成するのに最適なオプションです。そのため、一部のコントロールを下部に固定できます(サイズとアンカー)。

    ../../_images/stretch_viewport_keep_width.gif
  • Stretch Aspect = Keep Height: 画面を伸ばすときにアスペクト比を保ちます。画面が基本サイズよりも高い場合、黒いバーが上部と下部に追加されます(レターボックス化)。ただし、画面が基本解像度よりも広い場合、ビューポートは水平方向に拡大されます(さらに多くのコンテンツが右側に表示されます)。これを「水平方向に拡張」と考えることもできます。

    これは通常、水平にスクロールする2Dゲーム(ランナーやプラットフォーマーなど)に最適なオプションです。

    ../../_images/stretch_viewport_keep_height.gif
  • Stretch Aspect = Expand: 画面をストレッチするときはアスペクト比を維持しますが、ベースの幅も高さも維持しません。画面の縦横比に応じて、ビューポートは水平方向(画面が基本サイズよりも広い場合)または垂直方向(画面が元のサイズよりも高い場合)に大きくなります。

    ../../_images/stretch_viewport_expand.gif

Stretch Shrink(ストレッチの収縮)

Shrink 設定では、上記の Stretch オプションが既に提供しているものの上に、追加のスケーリング係数を追加できます。 デフォルト値の1は、スケーリングが発生しないことを意味します。

たとえば、Shrinkを4に設定し、Stretch ModeDisabled のままにすると、シーンの各ユニットは画面上の4×4ピクセルに対応します。

Stretch ModeDisabled 以外に設定されている場合、ルートビューポートのサイズは Shrink 係数によって縮小され、出力のピクセルは同じ量だけ拡大されます。 これは2Dゲームにはめったに役立ちませんが、3Dゲームを低解像度でレンダリングすることでパフォーマンスを向上させるために使用できます。

スクリプトから

To configure stretching at runtime from a script, use the get_tree().set_screen_stretch() method (see SceneTree.set_screen_stretch()).

ダウンサンプリングでのエイリアスの削減

If the game has a very high base resolution (e.g. 3840×2160), aliasing might appear when downsampling to something considerably lower like 1280×720. Aliasing can be made less visible by shrinking all images by a factor of 2 upon loading. This can be done by calling the method below before the game data is loaded:

VisualServer.texture_set_shrink_all_x2_on_set_data(true)

アスペクト比の処理

さまざまな解像度のスケーリングが考慮されたら、ユーザーインターフェイスもさまざまなアスペクト比に合わせてスケーリングするようにしてください。 これは anchors および/または containers を使用して実行できます。

視野のスケーリング

3Dカメラノードの Keep Aspect プロパティは、デフォルトで Keep Height スケーリングモード(Hor+ とも呼ばれます)になります。 ワイドスクリーンディスプレイは自動的に広い視野を使用するため、これは通常、デスクトップモードや横長モードのモバイルゲームに最適な値です。

ただし、3Dゲームをポートレートモードでプレイする場合は、代わりに Keep Width (Vert- とも呼ばれます)を使用する方が合理的です。 このように、アスペクト比が16:9(例: 19:9)よりも高いスマートフォンは、taller の視野を使用しますが、これはここではより論理的です。

Scaling 2D and 3D elements differently using Viewports

Using multiple Viewport nodes, you can have different scales for various elements. For instance, you can use this to render the 3D world at a low resolution while keeping 2D elements at the native resolution. This can improve performance significantly while keeping the HUD and other 2D elements crisp.

This is done by using the root Viewport node only for 2D elements, then creating a Viewport node to display the 3D world and displaying it using a ViewportContainer or TextureRect node. There will effectively be two viewports in the final project. One upside of using TextureRect over ViewportContainer is that it allows enable linear filtering. This makes scaled 3D viewports look better in many cases.

See the 3D viewport scaling demo for examples.