0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIでGodotのUIをつくる:ウィンドウサイズを変えても見切れないメインメニューと設定画面(検証)

0
Posted at

この記事は https://ziva.sh/blogs/godot-ui-ai の日本語版です(英語の原文はZiva.shが2026年11月10日に公開)。

ウィンドウのサイズが変わっても崩れないGodotのUIを、AIはつくれるのでしょうか。Godotエディターの中で動くAIエージェントのZivaに、Controlノードでメインメニューと設定画面をつくるよう依頼しました。Zivaは3分58秒で両方のシーンをつくり、ゲームを実行してSettingsとBackをクリックし、5つのウィンドウサイズでレイアウトを確認しました。見切れた部分はありませんでした。一方で、見落としもありました。Fullscreenのチェックボックスはチェックが入っていないとほとんど見えなかったのに、Zivaは「all controls showing」(すべてのコントロールが表示されている)と報告しました。よく見るように頼む2つ目のプロンプトで、Zivaはこの問題に気づいて修正しました。

レイアウトは、AIの助けがうまくいかなくなるところだと言われます。r/ClaudeAIでは、ある開発者が「Claude does not do a very good job in creating and modifying scenes for Godot … Elements are often partially clipped」(ClaudeはGodotのシーンの作成や修正があまり得意ではない……要素の一部が見切れることが多い)と書いています(スレッド)。r/aigamedevでは別の開発者が「I can burn through Claude's usage limit in a single session just trying to fix layouts and styling」(レイアウトとスタイルを直そうとするだけで、1回のセッションでClaudeの使用量の上限を使い切ってしまうことがある)と書いています(スレッド)。AIをまったく使わない場合でも、Godotフォーラムには「Making UIs almost takes up 80% of my time」(UIづくりに時間のほぼ80%を取られる)という投稿があります(スレッド)。

ZivaはZiva.shが開発しており、このテストもZiva.shが作成しました。

テストは2026年11月10日に、Linux上のGodot 4.7.2で実行しました。Zivaは開発ビルドを使い、モデルは既定のZiva Smart、自動承認(auto-approve)はオンです。1つのプロジェクトで1回だけ実行した結果なので、ベンチマークではなく1つの例として見てください。以下では、Zivaがつくったレイアウト(手作業でも同じものをつくれます)、Zivaによる結果の確認方法、見落とし、チェックリストを紹介します。

プロンプト

UIがまったくない新規プロジェクトで、次のプロンプトを一字一句そのまま渡しました(実際に使った英語のプロンプトと、その訳です)。

Make a main menu for my game in res://ui_demo/: the game title and Play, Settings and Quit buttons, centered. Settings should open a settings screen with a Master volume slider, a Fullscreen checkbox, a Resolution dropdown (1280x720 and 1920x1080) and a Back button that returns to the menu. Nothing should be clipped or overlapping, and it should still look right if the window is resized. Check it with screenshots and click through Settings and Back to make sure they work.

訳:ゲームのメインメニューをres://ui_demo/につくってください。ゲームのタイトルと、Play、Settings、Quitのボタンを中央に配置します。Settingsを押すと設定画面が開き、そこにMaster volume(マスター音量)のスライダー、Fullscreen(フルスクリーン)のチェックボックス、Resolution(解像度)のドロップダウン(1280x720と1920x1080)、メニューに戻るBackボタンがあるようにしてください。見切れたり重なったりする部分がなく、ウィンドウのサイズを変えても正しく表示されるようにしてください。スクリーンショットで確認し、SettingsとBackをクリックして動作することを確かめてください。

Zivaがつくったレイアウト

Zivaはres://ui_demo/に2つのスクリプトと2つのシーンを書きました。メインメニューは次のとおりです。

MainMenu (Control, Full Rect anchors, main_menu.gd)
├── Background (ColorRect, Full Rect)
├── MenuPanel (CenterContainer, Full Rect)
│   └── MenuBox (VBoxContainer, separation 20)
│       ├── Title (Label "My Game", font size 56)
│       ├── PlayButton (Button, custom_minimum_size 260 x 52)
│       ├── SettingsButton (Button, custom_minimum_size 260 x 52)
│       └── QuitButton (Button, custom_minimum_size 260 x 52)
└── SettingsScreen (instance of settings_screen.tscn, hidden)

設定画面は独自の不透明な背景を持つ独立したシーンで、メニューにインスタンス化され、必要になるまで非表示になっています。

SettingsScreen (Control, Full Rect anchors, settings_screen.gd)
├── Background (ColorRect, Full Rect)
└── Center (CenterContainer, Full Rect)
    └── Margin (MarginContainer, 24 px margins)
        └── VBox (VBoxContainer, separation 16)
            ├── Title (Label "Settings")
            ├── VolumeRow (HBoxContainer)
            │   ├── Label "Master Volume" (Expand)
            │   └── VolumeSlider (HSlider 0 to 1, min width 220)
            ├── FullscreenCheck (CheckBox)
            ├── ResolutionRow (HBoxContainer)
            │   ├── Label "Resolution" (Expand)
            │   └── ResolutionOption (OptionButton, min width 220)
            └── BackButton (Button, 240 x 48, Shrink Center)

Settingsを押すとMenuPanelが非表示になり、設定画面が表示されます。設定画面はback_requestedシグナルを発行し、それを受けたメニューは再び表示されて、Playにキーボードフォーカスを移します。Quitはget_tree().quit()を呼び出します。プロジェクトに読み込むゲームシーンがなかったため、Playはプレースホルダーのメッセージを出力するだけで、Zivaもそのことを伝えました。Zivaが書いた設定のハンドラーは次のとおりです。

func _on_volume_changed(value: float) -> void:
	var db: float = linear_to_db(value) if value > 0.0 else -80.0
	AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), db)

func _on_fullscreen_toggled(toggled_on: bool) -> void:
	var mode: DisplayServer.WindowMode = DisplayServer.WINDOW_MODE_FULLSCREEN if toggled_on else DisplayServer.WINDOW_MODE_WINDOWED
	DisplayServer.window_set_mode(mode)

func _on_resolution_selected(index: int) -> void:
	if index < 0 or index >= RESOLUTIONS.size():
		return
	DisplayServer.window_set_size(RESOLUTIONS[index])
	_center_window()

設定は、ゲームを起動し直すと引き継がれません。プロンプトで求めておらず、Zivaも追加しませんでした。必要な場合は、user://のConfigFileに値を書き込んでください。

このレイアウトが見切れない理由

Godotで見切れるUIの大半は、手で配置したコントロールが原因です。コントロールのオフセットはアンカーポイントからのピクセル距離で、アンカーポイントは既定では親の左上隅です(Size and anchors)。幅1152ピクセルのウィンドウでx = 900に置いたボタンは、幅640ピクセルのウィンドウでは外に出てしまいます。

上のレイアウトには、手で配置した子の位置が1つもありません。

  • ルートがウィンドウ全体を埋める。 MainMenu、Background、MenuPanelはアンカープリセットのFull Rect(両軸ともアンカーが0から1)を使っているので、常にウィンドウと同じ大きさになります。
  • 中央寄せはCenterContainerが担う。 CenterContainerは「automatically keeps all of its child controls centered within it at their minimum size」(すべての子コントロールを最小サイズのまま自動で中央に保つ)コンテナーです(Using Containers)。
  • 行はボックスコンテナーが積み重ねる。 コンテナーの中では「all children Control nodes give up their own positioning ability」(子のControlノードはすべて、自分で位置を決める機能を手放す)ため(同じページ)、サイズが変わるとすべてが配置し直されます。
  • 大きさは最小サイズで決まる。 ボタンの大きさはcustom_minimum_sizeで決まります。設定の各行のラベルにはExpandが設定されているので、ラベルと幅220ピクセルのスライダーやドロップダウンが重ならずに行を分け合います。

限界が1つあります。コンテナーは子を最小サイズより小さくしません。Zivaのメニューのボックスは260 x 293ピクセルなので、高さが293ピクセル未満のウィンドウには収まらなくなります。とても小さいウィンドウでも動かす必要がある場合や、大きな画面でUIを拡大したい場合は、Project Settings > Display > Window > Stretch > Modeをcanvas_itemsに設定してください(Multiple resolutions)。Zivaのプロジェクトは既定のDisabledのままだったので、1920 x 1080のウィンドウでは、メニューは同じピクセルサイズのまま、大きな画面の中央に表示されます。

Zivaの確認方法

Zivaのrun_sceneツールは、エディターからシーンを実行し、入力を送り、スクリーンショットを返します。Zivaはこのツールを3回使いました。

  1. メニューを実行し、スクリーンショットを見る。このとき、実行時の出力にあった整数除算の警告も修正しました。
  2. もう一度実行し、Settingsと書かれたボタンをクリックする。スクリーンショットには設定画面が写っており、Zivaは「Settings screen opens with all controls showing, nothing clipped.」(設定画面が開き、すべてのコントロールが表示されていて、見切れもない)と書きました。
  3. もう一度実行し、Settings、Backの順にクリックする。スクリーンショットには、Playにフォーカスがあるメニューが写っていました。

run_sceneはプロジェクトのウィンドウサイズ(ここではGodotの既定の1152 x 648)でゲームを実行し、そのサイズを変えられないため、スクリーンショットだけではサイズ変更を確認できませんでした。Zivaはそのことを指摘したうえで、いくつかのウィンドウサイズでメニューを読み込み、メニューのボックスと設定のボックスがウィンドウ内に収まっているかを確認するGDScriptのテストを書きました。最初の計測では、1152 x 648でどちらも収まっていないという結果になりました。Zivaは最初のフレームではまだレイアウトが適用されていなかったと判断し、ウォームアップを入れて1152 x 648を計測し直し、800 x 450と3840 x 2160も加えました。2回の実行を合わせると、640 x 360、800 x 450、1152 x 648、1920 x 1080、3840 x 2160で合格しました。

そのあと、プロジェクトのコピーで独自のチェックも実行しました。1152 x 648、640 x 360、1920 x 1080、800 x 600のどのサイズでも、表示されているControlがウィンドウの外に出たり、中身より小さくなったりすることはありませんでした。Settingsで設定画面が開き、Backでメニューに戻りました。

Zivaが最初につくった設定画面を、独自のチェックで4つのウィンドウサイズ(640 x 360、1152 x 648、1920 x 1080、800 x 600)で描画したもの。どのサイズでも中身は中央に収まり、ウィンドウの内側にある。

見落とし:見えないチェックボックス

どちらのチェックも、問題のある設定画面を合格にしていました。Godotの既定のテーマでは、チェックが入っていないCheckBoxのボックスは暗い色です。Zivaの暗い背景の上ではほとんど見えなくなり、「Fullscreen」がただのラベルに見えました。Zivaのスクリーンショットにもそれが写っていましたが、Zivaはすべてのコントロールが表示されていると報告しました。独自のジオメトリのチェックでも見つけられませんでした。チェックボックスは大きさも正しく、ウィンドウの中に収まっていたからです。

同じチャットで2つ目のプロンプトを送りました。

Look closely at the settings screen in a screenshot. Is every control easy to see and use? Fix anything that isn't, then show me the settings screen again.

訳:設定画面をスクリーンショットでよく見てください。どのコントロールも見やすく、使いやすいですか?そうでないものを修正してから、もう一度設定画面を見せてください。

今回Zivaは前のスクリーンショットを開き、Fullscreenのチェックボックスが「looks like plain centered text with no visible indicator」(目に見えるインジケーターのない、中央寄せのただのテキストに見える)と述べました。同じ背景の上にチェックありとチェックなしのCheckBoxを置いた使い捨てのシーンをつくって実行し、ボックスが見えるのはチェックありのほうだけだと確かめました。そのうえで、チェックありとチェックなしのアイコンを独自に描いてチェックボックスのThemeに設定するコードをsettings_screen.gdに追加し、メニューをさらに2回実行して、Settings、Fullscreenの順にクリックし、両方の状態を確認しました。そのあとの独自のチェックも同じ4つのサイズで合格し、チェックボックスの枠が見えるようになっていました。

2つ目のプロンプトの前と後のZivaの設定画面。左:チェックが入っていないFullscreenのチェックボックスには、ボックスがほとんど見えない。右:Fullscreenの横に、明るい枠線のボックスがある。

この修正について、知っておきたいことが2つあります。1つ目に、スクリプトでアイコンを1ピクセルずつ描く方法でも動きますが、チェックボックス1つに約60行のコードはかなりの量です。自分のプロジェクトでは、チェックボックスのアイコンを設定したThemeリソースをルートのControlに設定すれば、その下にあるすべてのCheckBoxに同じ効果があります。テーマはそのコントロールとその子に適用されるからです(GUI skinning)。2つ目に、Zivaは使い捨てのシーンui_demo/_tmp_check.tscnをプロジェクトに残しました。Zivaは返答の中でそのことに触れ、「didn't delete it since removal wasn't requested」(削除は依頼されていなかったので消していない)と書いて、削除を申し出ました。

時間とコスト

  • 1つ目のプロンプト: 3分58秒。既定のモデルZiva Smartで、Zivaの使用量は$0.033。
  • 追加のプロンプト: 4分6秒、$0.036。

このテストでわからないこと

シンプルなUIが1つ、既定のテーマ、1回の実行だけです。FullscreenとResolutionが実際のデスクトップのウィンドウを変えるかどうかや、コントロール間のキーボードとゲームパッドでの移動は確認していません。Zivaが指摘したとおり、Zivaの実行ウィンドウはエディターに埋め込まれていて、ウィンドウモードにしか対応していません。UIが大きい場合、独自のテーマを使う場合、別のモデルを使う場合は、結果が変わる可能性があります。

チェックリスト:見切れないGodotのメニューと設定画面

自分でつくる場合もAIに頼む場合も、次の手順は上のレイアウトに沿っています。

  1. ルートのControlを追加し、ビューポートの上のツールバーにあるアンカープリセットのメニューからFull Rectを選ぶ。
  2. 背景のColorRectを追加し、これもFull Rectにする。
  3. CenterContainer(Full Rect)を追加し、その中にVBoxContainerを入れる。タイトルとボタンはVBoxContainerに入れる。
  4. ボタンの大きさは、ハンドルをドラッグするのではなくCustom Minimum Sizeで決める。
  5. 設定画面は、独自の背景を持つ独立したシーンにする。メニューにインスタンス化して非表示にし、メニューのスクリプトから表示と非表示を切り替える。ラベルとコントロールの行にはHBoxContainerを使い、ラベルにExpandを設定する。
  6. 複数のウィンドウサイズで確認する。シーンを実行してウィンドウのサイズを変えるか、下のようなスクリプトを実行する。
  7. すべての画面のスクリーンショットを、実際の背景の上で、すべての状態(チェックありとなし、フォーカスありとなし)について見る。レイアウトのチェックでは、コントロールが見えにくいことはわからない。

Zivaがやったことをもとにした、短いサイズチェックです。プロジェクトのフォルダーに保存して、godot --headless --path . --script check_layout.gdを実行してください。

extends SceneTree

func _initialize() -> void:
	var menu: Control = load("res://ui_demo/main_menu.tscn").instantiate()
	root.add_child(menu)
	# The window applies its own size on the first frame, so measuring before this reads a stale layout.
	await process_frame
	for size: Vector2i in [Vector2i(640, 360), Vector2i(1152, 648), Vector2i(1920, 1080), Vector2i(400, 240)]:
		root.size = size
		for i in 4:
			await process_frame
		var box: Rect2 = menu.get_node("MenuPanel/MenuBox").get_global_rect()
		print(size, " menu fits: ", Rect2(Vector2.ZERO, Vector2(size)).encloses(box))
	quit()

Zivaのメニューでは、最初の3つのサイズでtrue、400 x 240でfalseが出力されます。400 x 240の結果は、上で説明した最小サイズの限界によるものです。

Zivaを自分のUIで試すには、インストールを参照してください。同じ種類のテストを、壊れたシェーダーとコリジョンのバグでも実行しています(どちらも英語)。

よくある質問

AIでGodotのUIをつくれますか?

今回のテストでは、おおむねつくれました。Godotエディターの中で動くAIエージェントのZivaに、Controlノードでメインメニューと設定画面をつくるよう依頼しました。Zivaは約4分で両方のシーンをつくり、実行中のゲームでSettingsとBackをクリックし、5つのウィンドウサイズでレイアウトを確認しました。見落とした問題が1つあり、チェックが入っていないFullscreenのチェックボックスが暗い背景でほとんど見えませんでした。よく見るように頼む2つ目のプロンプトで、Zivaはこれに気づいて修正しました。2026年11月10日に1つのプロジェクトで1回実行しただけなので、ベンチマークではなく1つの例として見てください。

ウィンドウのサイズを変えても見切れないGodotのメインメニューは、どうつくればよいですか?

手で配置した位置ではなく、コンテナーで組み立てます。ルートのControlにアンカープリセットのFull Rectを設定して、常にウィンドウと同じ大きさにします。Full RectアンカーのCenterContainerを追加してその中にVBoxContainerを入れ、ボタンの大きさはCustom Minimum Sizeで決めます。コンテナーの子は自分で位置を決めなくなるので、ウィンドウのサイズが変わるたびに、コンテナーが子を中央に配置し直します。コンテナーは子を最小サイズより小さくしないため、とても小さいウィンドウにはcanvas_itemsなどのストレッチモードが別に必要です。

音量、フルスクリーン、解像度を変えられる設定メニューをGodotでつくるには?

設定画面を独立したシーンにして、メニューのシーンにインスタンス化し、メニューのスクリプトから表示と非表示を切り替えます。コントロールは次のとおりです。0から1のHSliderで、AudioServer.set_bus_volume_dbとlinear_to_dbを使ってMasterバスの音量を設定します。CheckBoxでDisplayServer.window_set_modeをフルスクリーンとウィンドウモードの間で切り替えます。OptionButtonでは、選んだ解像度を渡してDisplayServer.window_set_sizeを呼び出します。再起動後も値を残したい場合は、ConfigFileで保存します。

GodotのUIをさまざまなウィンドウサイズでテストするには?

シーンを実行してゲームのウィンドウのサイズを変えるか、短いスクリプトを実行します。スクリプトでは、ルートのウィンドウサイズをいくつかの値に設定し、コンテナーのレイアウトが終わるまで数フレーム待ってから、各コンテナーの矩形がウィンドウ内にあるかを確認します。最初の計測の前には1フレーム待ってください。今回のテストでは、Zivaの最初の計測は古いレイアウトを読んでいました。レイアウトのチェックではコントロールが見やすいかどうかはわからないので、スクリーンショットも見てください。

GodotのCheckBoxが暗い背景で見えないのはなぜですか?

Godot 4.7.2の既定のテーマでは、チェックが入っていないCheckBoxのボックスは暗い色で描かれます。Zivaが選んだ暗い背景(Color(0.09, 0.1, 0.14))では、チェックなしのボックスはほとんど見えなくなりましたが、チェックありのボックスははっきり見えました。Themeリソースでチェックありとチェックなしのアイコンを独自に設定するか、チェックボックスの後ろの背景を明るくすれば直ります。

この記事の原文(英語):https://ziva.sh/blogs/godot-ui-ai

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?