システム設定の構築【Unity6】

絶対調味ロジック

最後のUI設定画面にとりかかりました。
各設定画面の中で一番楽かなと思って、最後にとっていたのですが、意外に時間を取られてしまいました。
主にChatGPTとの喧嘩のせいですが…(#^ω^)

実装自体はシンプルだったのに、そこに行くまでの過程でやたらと横道に逸らしてくるChatGPT5でした。
今回は、5の制限が切れて、低レベル版に切り替わった後の方が、余計な考えなしで高速でした。

結論:Claude賢い…

こちらのシステム設定作成案

画面モード:・Windowed・Fullscreen 2択ボタン

ウィンドウサイズ(解像度)
・固定プリセットのみ「960×540」「1280×720」「1600×900(開発環境)」3択ボタン
・ユーザーリサイズ不可
・フルスクリーン時はウィンドウサイズボタンはグレーアウト(触れないように)
・ウィンドウサイズの変形後は中央になる仕様。ちらつきはいったんそのまま。

初期設定に戻す:ボタン 初期設定 :1280×720
・各設定の反映と保存:AudioとTextと(上記スクリプト)同じ、即反映で画面閉じて保存。
・Steam対応は考えていない。とりあえずこの形での実装を目指すのが目的。

このシンプルな案になるまでもChatGPTとひと悶着ある始末w

フルスクリーンの方法:Unityには2つの方法が実装されている、さぁどっち。
ボーダーレスの有無:あったほうがいい、なくていいの争い。
ウィンドウリサイズの有無:なしと言ってるのに、設計案でぶっこんでくる。
初期設定に戻す挙動:他のUI画面と同じ挙動でと言ってるのに「それは危険な考え!」を主張してくる。
・一番彼(ChatGPT)がかたくなだったのが「1280」以下の解像度の必要性:そんな小さいの必要ない説。
テストのためだけでもいいので、まずはそのサイズも実装と強く言って、しぶしぶ了承してくる始末。
サイズ変更に伴うUI崩れにも異常な熱意がありました。
steamで出す予定なら完全に対応しないといけない、ユーザー環境は様々、それを考慮に入れたうんぬんかんぬん…
システム設定をまずは実装!といってるのにUI崩れるのは有り得ないと話脱線。

システム自体の挙動も他のUI画面と同じにとスクリプトを見せたら、
現在のManager運用の欠点を指摘されました。
それは良くて将来的にManager関連もリファクトしたいとも思っていましたが、
その話題を引きずりすぎて話が進まなかったりもしました。

スクリプトの修正も、1を直して2にして、次は2を直をしてほしいのに1を直し始めていたり、
スクリプトの中身を確認する作業が多くなってきているように感じました。
元スクリプトが8000文字あるのに、「最新完成版です!」で2500文字とかで出されていたり…
プロンプトの問題でもあるのですが、前のようにはいかなくなっている違和感を感じてます。

Geminiも最近はそんな感じで、指摘すると
「直前の問題に集中しすぎて、前の問題がおそろかになってました」
と言ってくること数回…w

そんなこんなで、とりあえずの実装もできずに3~4時間潰してました(#^ω^)

結局、なんとか書き出してもらったスクリプトをClaudeさんに診てもらって、
テキパキと実装と不具合を直してもらって完了です。

システム設定の設計案

画面モード(Windowed / FullscreenWindow)

  • トグル形式の 2択ボタン
  • 変更時に即反映
  • フルスクリーン選択時には解像度選択を無効化(グレーアウト)
  • フルスクリーン切替は「Screen.fullScreenMode」+「Screen.SetResolution」で対応可能

ウィンドウサイズ(解像度

  • 3種類固定プリセット:「960×540」「1280×720」「1600×900」
  • ユーザーリサイズ不可
  • フルスクリーン時は無効化
  • 解像度変更時に「中央配置」 → Screen.SetResolution(width, height, fullscreen, refreshRate)
  • ちらつきは現状許容
  • 初期値:1280×720

保存/初期化

  • 初期化ボタンで「1280×720 / Windowed」に戻す
  • 設定変更は即反映
  • パネル閉じるときに保存
  • 保存先は「Sys_SystemSettingsManager」で管理

既存システムとの統合

  • Audio/Text と同じ UI パターン
  • ボタンやスライダーの値は「Sys_SystemSettingsManager」が保持
  • Preview 的な UI は不要(解像度は即反映で画面自体が変化するため)

新規スクリプト

Sys_SystemSettingsManager(Singleton)

  • 設定項目
    • 画面モード(Windowed / Fullscreen)
    • 解像度(プリセット 960×540 / 1280×720 / 1600×900)
    • 永続化:Audio/Text と同じ JSON 方式
    • デフォルト値:Windowed 解像度:1280×720
    • 即反映機能:UI操作で即画面設定を反映
    • 保存:画面を閉じたタイミングで JSON 保存

UI_SystemSettingsPanel

  • UI_PanelBase を継承
  • ボタン配置
    • 画面モード(Windowed / Fullscreen)2択
    • 解像度 3択ボタン
    • 初期設定に戻すボタン
  • フルスクリーン時は解像度ボタンを無効化
  • 選択内容を UI で反映
  • 初期値に戻す:1280×720 / Windowed

動作フロー案

  1. UI が開く → Manager から現在設定を取得 → ボタン初期状態をセット
  2. ユーザーが Windowed / Fullscreen を選択 → 即反映 → 解像度ボタンを有効/無効切替
  3. ユーザーが解像度ボタンを押す → 即反映 → 画面中央に配置
  4. 初期化ボタン押下 → Manager が初期値に戻す → UI 更新 → 画面反映
  5. パネル閉じる → Manager.SaveAll() → 永続化

システム設定の実装

サイズ変更が機能しない修正を何度か行い、実装自体はすんなりとできました。

UIズレはとりあえず放っておきます。

問題の修正

フルスクリーン時の色相変化

フルスクリーンにすると、画面が暗くなります。

ExclusiveFullScreen」方式でフルスクリーンにすると色相は直りましたが、
デスクトップのあらゆるウィンドウ位置がバグってしまい、戻すのが大変でした。

他に解決法と原因を探っていると
現状、Graphics API が Direct3D12 に優先されている
Direct3D12は「FullScreenWindow」方式時にsRGBの処理がDirect3D11と異なります。
LinearカラースペースでD3D12を使うと、
フルスクリーン時に色変換が正しく行われないケースがUnity6で報告されています。
とのこと。

「ProjectSettings」>「Player」> Auto Graphics API for Windows

Direct3D12」を削除して再起動後、色相は直りました。

  • Auto Graphics API for Windows → チェックなし
  • Graphics API for Windows → Direct3D11のみ
  • Use DXGI flip model swapchain for D3D11 → チェックあり
  • FullScreenMode → FullScreenWindow(コードそのまま)

サイズ変更した際に、そのサイズでフルスクリーンにすると、ぼやけてしまう問題もいっしょに修正します。

  • フルスクリーン時 → 常にモニターのネイティブ解像度(例:1920×1080や2560×1440)で表示するように
  • ウィンドウ時 → 選択した解像度のまま

UIズレ

配置しているしている全ての「Canvas」の「CanvasScaler」設定を変更します。

とりあえず問題なくUIは収まってくれています。
UI設置の仕方(多別環境対応)にも癖がありそうなので、後々お勉強することにはなりそうです。

実機での挙動

今回は初めて「ビルド」をしてみて実際のアプリでのテストプレイになりました。
初回にいきなりUIオブジェクトがすべてピンクになっていて仰天です。

軽量化のためと思ってデフォルト設定のシェーダーをすべて削除していたためでした。
この段階で気付けて良かったです。

これでコンフィグ系はすべて実装できたことになります。
当時は調整関連の実装が、
ここまで無難に終えることができると思っていなかったので、かなりホッとしています。

すべて新時代のAiのおかげなのです。
0から勉強して実装」ははっきり言って現実的ではなかったと思います。
ギリギリ凄い時代を味合わせてもらった、というところでしょうか。

あとは「メニュー画面」を作成して、自動ソートにするなどの細かい作業が残っています。

プロジェクトまとめ

構成ファイル

  • Sys_SystemSettingsManager.cs:設定の保存・適用ロジック
  • UI_SystemSettingsPanel.cs:UI操作・表示制御
  • Sys_Flag_Manager.cs:変数の永続化(JSON保存)

実装仕様

画面モード

  • ウィンドウ / フルスクリーンの2択トグル
  • フルスクリーン時はモニターのネイティブ解像度で表示
  • フルスクリーン時はウィンドウサイズボタンをグレーアウト

ウィンドウサイズ

  • 3プリセット固定:960×540 / 1280×720 / 1600×900
  • ウィンドウモード時のみ有効
  • 初期値:1280×720

保存

  • SYS_SCREEN_FULLSCREEN(Bool)
  • SYS_SCREEN_RESOLUTION(Int)
  • 「Sys_Flag_Manager」のSYS_プレフィックスにより変更時に自動でJSON保存

初期化

  • 初期設定ボタンで1280×720 / ウィンドウに戻す

実装上の重要ポイント

フルスクリーン時の解像度

if (full)
{
    Resolution native = Screen.currentResolution;
    Screen.SetResolution(native.width, native.height, FullScreenMode.FullScreenWindow);
}
else
{
    Screen.SetResolution(res.x, res.y, FullScreenMode.Windowed);
}

フルスクリーン時は選択解像度ではなくモニターのネイティブ解像度を使う。
これをしないと960選択中にフルスクリーンにすると画質が落ちる。

FullScreenModeの選択理由

FullScreenWindow(ボーダーレス)を採用。
ExclusiveFullScreenは他アプリのウィンドウ状態を破壊するケースがあったため却下。

Direct3D12を使わない理由

D3D12 + Linear ColorSpace + FullScreenWindowの組み合わせで
フルスクリーン時に色相が変わるUnity6の既知問題が発生した。

Auto Graphics API をOFFにしてD3D11のみを指定することで解決。

Project Settings → Player → Other Settings
Auto Graphics API for Windows → チェックなし
Graphics API → Direct3D11のみ
Use DXGI flip model swapchain for D3D11 → チェックあり

Canvas Scalerの設定

  • UI Scale Mode → Scale With Screen Size
  • Reference Resolution → 1600 x 900
  • Screen Match Mode → Match Width Or Height
  • Match → 0.5

最終的なApplySettings()

public void ApplySettings()
{
    bool full = GetFullscreen();
    ResolutionPreset p = GetResolutionPreset();

    Vector2Int res = p switch
    {
        ResolutionPreset.R960x540 => new(960, 540),
        ResolutionPreset.R1280x720 => new(1280, 720),
        ResolutionPreset.R1600x900 => new(1600, 900),
        _ => new(1280, 720)
    };

    if (full)
    {
        Resolution native = Screen.currentResolution;
        Screen.SetResolution(native.width, native.height, FullScreenMode.FullScreenWindow);
    }
    else
    {
        Screen.SetResolution(res.x, res.y, FullScreenMode.Windowed);
    }

    Sys_Flag_Manager.Instance.SaveGlobal();
}

コメント