LoginSignup
2
0

[Godot 4.2] ピクセルパーフェクト(ドット絵)と高解像度のUIを同じ画面に出す(修正版)

Last updated at Posted at 2024-03-12

これは前の記事の修正版ですが、必要なことは(一部コピペしつつ)この記事にすべて書いてあるため、前の記事を読む必要はありません。
一応、前の記事は失敗例として一部加筆して残してあります。

今回やること

ドット絵で作られたキャラクターや背景などをピクセルパーフェクトで表示しつつ、高解像度のUIを前面に表示します。

公式ドキュメントの複数の解像度 — Godot Engine (4.x)の日本語のドキュメントを読むと、一般的なシナリオの1つとして「ゲーム全体を低解像度で作ってピクセルパーフェクトで表示する方法」が書かれていますが、今回はそれに加えて高解像度のUIも表示します。

つまるところ、このような画面です。
1600x900.png

他の解像度のスクリーンショット

320x180
320x180.png

1920x1080
1920x1080.png

背景やキャラクター(の素体)のドット絵はピクセルパーフェクトで表示されていますが、画面中央と左上のUI要素は高解像度で表示されています(原寸表示で厳密な確認ができます)。

方法

主に以下の3点を行います。

  • プロジェクト設定にて、ビューポートの解像度とストレッチモードの指定をする
  • 解像度を操作するボタンなどを用意する
  • SubViewportContainer を用いてドット絵を扱うシーンを表示させる

単純に画面要素のすべてがドット絵であるかそれと同等の低解像度を持つようなゲームを作る場合、公式ドキュメントのシナリオ例にあるようなやり方で問題ありません。
しかし今回は高解像度のUIも表示するため、プロジェクト設定の解像度は高い値にします。
そして、ゲーム画面の解像度がピクセルパーフェクトの条件を満たすようにスクリプト等で制御します。

プロジェクト設定について

プロジェクト設定で変更するのは以下の3点です。
いずれも「一般」-「表示」-「ウィンドウ」内にあるプロパティです。

  • ビューポートの幅、高さを 19201080 にする1
  • 「サイズを変更可能」のチェックを外し、ウィンドウサイズの変更を禁止する
  • 「ストレッチ」-「モード」を canvas_items にする

ウィンドウサイズ変更を禁止していますが、これはそもそも、ピクセルパーフェクトを実現するためにはドット絵を整数倍スケーリングかつアスペクト比固定で表示する必要があるためです。
当然ながら解像度変更は必要な機能なので、後で解像度を選択するための OptionButton を追加してスクリプトから解像度変更を行う機能を追加します。

ストレッチモードを viewport にした場合、高解像度の表示が若干汚くなります。
各 CanvasItem を 1920x1080 の解像度に合わせてアンチエイリアスなどをかけてビューポートに描画した後、その画面を再び拡大・縮小するためです(もっと詳しい解説が公式ドキュメントにあります)。

プロジェクト設定のスクリーンショット

プロジェクト設定.png

解像度をスクリプトから変更する

Window.size に解像度を表す Vector2i を代入します。

change_resolution.gd
# ウィンドウサイズを 320x180 に変更する
get_window().size = Vector2i(320, 180)

Node.get_window() を使えばウィンドウのインスタンスを取得できます。

あとは OptionButton などで解像度を指定できるようにすれば、実行中に解像度を変更できるようになります。

選択肢として用意する解像度は、ドット絵をピクセルパーフェクトで表示できる条件を満たすもののみにすることを忘れないでください。

ドット絵を SubViewport を使って表示する

ドット絵は一旦小さな画面に描画して、その画面を整数倍に拡大表示することで高解像度の要素と共存させます。
そのための「小さな画面」として SubViewport を使います。
そしてその画面を拡大表示するために SubViewportContainer を使います。

「小さな画面」の解像度は、ドット絵を作るときにイメージしていた画面サイズを使います。
ただし、この解像度を整数倍するとプロジェクト設定の解像度になるようにする必要があります。
今回は小さなドット絵なので、 320x180 です。6倍すると 1920x1080 になります。

シーン構成

まず、シーン内に SubViewportContainer を追加します。
そして SubViewportContainer の子に SubViewport を追加します。
SubViewport の子がすべて「小さな画面」に描画され、出来上がった画面が SubViewportContainer 上に表示されます。
ただし、SubViewport の子はシーンビューで動かしたり拡縮・回転したりすることができません。
別のシーンとして作ってからインスタンス化すると作りやすいでしょう。
最終的にはこのようなシーンツリーが出来上がります。

scene_tree.png

SubViewport の設定

ドット絵をピクセルパーフェクトで表示するには前述の条件に加え、ドット絵の表示座標がサブピクセル(ピクセルの中間地点)上に来ないようにする必要があります。
そのために Snap 2D Transform To PixelSnap 2D Transform To Pixel をオンにします(実際にはインスペクタ上のチェックボックスを操作します)。

さらに、この Viewport 上でのデフォルトのフィルタ処理をニアレストネイバー法にするために、 Default Texture FilterNearest にします。

sub_viewport.png

Snap 2D ~ の2つのプロパティ、名前がなんとなくそれっぽいですが説明が一切書いてありません。
そのため詳細が不明ですが、とりあえずそれぞれの片方だけで試してみたところドット絵が崩れました。
崩れたドット絵.png

SubViewportContainer の設定

こちらではドット絵を鮮明に拡大表示するための設定をします。

まずは Size をプロジェクト設定の解像度と同じ値にします。
画面いっぱいに SubViewportContainer が広がります。

次に Stretch をオンにします。そうすると子の SubViewport のサイズが自動で設定されるようになります。
プロジェクト設定の解像度 / ドット絵を表示する解像度 で求められる値をその下の Stretch Shrink に設定します。
元々整数倍になるように解像度を決めていたはずなので、ここにも整数が入るはずです。

最後に、 FilterNearest に変更して終わりです。

sub_viewport_container.png

完成

これで、文字を含む高解像度の要素を鮮明に表示しつつ、ドット絵をピクセルパーフェクトで表示することができます。
SubViewportContainer を使っているため、ドット絵のクリック判定も行うことができます。

参考文献

  1. 1920x1080 は公式ドキュメントで「最も広く使われている解像度」として紹介されていました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0