今回のコンセプトがビデオUIなので、中身の設定もそれっぽくしてみました。
ドット絵では賛否分かれる「ぼかし」も少しエフェクトしてみました。
パッキリとしているよりもビデオ感は強くなったと思います。
ボタンのビジュアル効果
概要
メニュー画面の各ボタン専用スクリプトに次いで、
ボタンのビジュアル効果だけを独立させた新規スクリプト「UI_ButtonVisual」を作成しました。

設定できるボタン表現は、「ノーマル」「ホバー」「プレス」の3状態にしました。
プレス時のアニメーションバージョンは削除しました。
前と同じように、他画像と連動できるように複数指定で増減可能にしています。
後々必要になり「セレクト」「無効」「トグル」も追加することになります。
基本方針
- IPointerEnterHandler 系インターフェースで状態検知
- Buttonの Transition = None を前提(Inspectorで手動設定、Editorのみ警告で検知)
- OnDisable で必ずNormalにリセット(SetActiveベースのパネル開閉に対応)
Mode構成
| Mode | 用途 |
|---|---|
| Normal | 通常。Hover/Pressはポインターフラグで制御 |
| Selected | タブ・排他選択ボタンの選択中状態 |
| Disabled | interactable=false時の非活性状態 |
| Toggle | ON/OFFそれぞれにNormal/Hover/Pressを持つ |
Targetフィールド構成(1Targetあたり)
- 通常:normal / hover / press
- Selected:selected
- Disabled:disabled
- Toggle OFF:toggleOffNormal / toggleOffHover / toggleOffPress
- Toggle ON:toggleOnNormal / toggleOnHover / toggleOnPress
外部呼び出しAPI
SetNormal();
SetSelected();
SetDisabled();
SetToggle(bool isOn);
共通パターン
// Awakeでキャッシュ
private UI_ButtonVisual visualXxx;
visualXxx = btnXxx?.GetComponent<UI_ButtonVisual>();
// RefreshAll/UpdateXxx内で呼び出し
visualXxx?.SetSelected();
visualXxx?.SetNormal();
visualXxx?.SetDisabled();
visualXxx?.SetToggle(bool);
メニュー画面

新規スクリプト「UI_ButtonVisual」を各ボタンにアタッチし、それぞれの画像を指定して出来上がりです。
画像の「ぼかし」効果を狙い、設定や画像圧縮を変更しました。

「ぼかし」をするために画像圧縮をしているので、サイズも減って一石二鳥効果です。

仕上げに、少し粗い「走査線」もつけて完成です。
やはり「ぼかし」が入ると、画面越し表現に近づきますね。
使用フォントについての設定も「フォントの個別設定(ぼかしやシャープなど)」で詳しく解説しています。
システム設定
■ UI_SystemSettingsPanel
- ウィンドウモード(Windowed/Fullscreen)→ Selected
- 解像度3種 → Selected、フルスクリーン時は Disabled
- リセットボタン → フルスクリーン時 Disabled


「システム設定」「音量設定」「テキスト設定」には専用の「タブボタン」を採用しているので、
「Sys_ConfigTabController」を対応するように改修しました。
- spriteOn/Off・colorOn/Off フィールド削除
- RefreshTabStates() のビジュアル処理を SetSelected() / SetNormal() に置き換え
そして、ここのシステム画面で「セレクト状態」と「トグル状態」も必要となったため、
「UI_ButtonVisual」自体にも機能を追加しています。

音量設定
■ UI_AudioSettingsPanel
- ミュートボタン4種 → Toggle(ON=ミュート中)
- Masterミュート時に子チャンネルボタン → Disabled
- muteOnColor / muteOffColor フィールド削除

テキスト設定
■ UI_TextSettingsPanel
- スキップモード(SkipAll/SkipRead)→ Selected(排他)
- ルビ設定 → 当初Selected2ボタン構成からToggle1ボタンに変更、btnRubyOff 削除

バックログ

バックログ画面にも「閉じるボタン」を設置できるようにし、
記述設定だった名前・セリフの「色」と「サイズ」をインスペクターで調整できるように改善しました。

ダイアログ画面

背景に砂嵐アニメを配置してみました。
アニメーションは専用スクリプトで動かしています。

セーブロード画面
■ UI_SaveLoadPanel
- titleText(TextMeshPro)と titleImage(Image)を追加
- titleText はセーブ/ロードモードに応じてコードで自動切替
- titleImage はInspectorでアサインするだけ、コード側から操作しない
- どちらも未アサインでもエラーなし

いつからかできていると錯覚していた「メイン画面だけのスクリーンショット」
どうやら「スロット」を複数にした時点ですでにできておらず、
いままでずっとセーブ画面のスクリーンショットが表示されていたようでした。
いろいろと工夫してもらったのだけれど、撮影タイミングがうまくいかず、
結果的に「メニュー画面を開く直前に撮影しておき、セーブ時にあてがう」という方法で落ち着きました。
■ 原因:
Sys_ScreenshotManager.CaptureScreenshot() は WaitForEndOfFrame で1フレーム待って撮影するだけで、
撮影タイミングでセーブパネルが表示されたままだった。
■ 試みた解決策と結果:
CanvasGroupで透明化 → SetActive よりマシだがチカつきが発生。
根本解決にならず。
■ 最終解決策:撮影タイミングをセーブ時から切り離す:
メニュー画面を開く直前(ゲーム画面が完全に表示されている状態)に撮影してメモリにキャッシュ。
セーブ時はキャッシュ済み画像をファイルに書き出すだけ。
■ 変更スクリプト
Sys_ScreenshotManager
- CaptureAndCache() 追加:撮影してメモリに保持
- SaveCachedScreenshot(path) 追加:キャッシュをファイル書き出し
- ClearCache() 追加:キャッシュ破棄
- 旧 CaptureScreenshot() はAutoSave等のために残置
Sys_SaveManager
- SaveRoutine() からスクリーンショット撮影処理を削除
- 代わりに SaveCachedScreenshot() を呼ぶだけに変更
UI_Manager
- メニューを開く処理を CaptureAndOpenMenu() コルーチンに変更
- メニュー開封直前に CaptureAndCache() を実行してからパネルを開く
UI_MenuPanel
- btnSave のリスナーは通常の SavePanel?.Open() に戻す
- CaptureAndOpenSave() コルーチンは削除
注意点:
・セーブ画面を開く経路が増えた場合、その箇所でも CaptureAndCache() を呼ぶ必要がある。
・AutoSaveはゲーム画面で実行されるため従来の CaptureScreenshot() のままで問題なし
■ キャッシュのメモリサイズ(解像度に依存)
| 解像度 | 非圧縮テクスチャサイズ(RGBA32) |
|---|---|
| 1280×720 | 約3.5MB |
| 1600×900 | 約5.5MB |
| 1920×1080 | 約8MB |
常に1枚だけ保持(上書き)なので、最大でも8MB程度です。
ロースペックPCでも問題ないレベルです。
■ 処理負荷
CaptureScreenshotAsTexture() は WaitForEndOfFrame 後に1フレームだけ処理が走ります。
メニューを開くたびに1回だけなので、頻度としても問題ありません。
■ キャッシュクリア
UI_MenuPanel:
タイトル遷移時に ClearCache() を呼び、キャッシュが確実に破棄されるようにしました
Sys_ScreenshotManager:
シーン遷移時に OnDestroy で ClearCache() が呼ばれ、
タイトル遷移時は Co_ReturnTitle() で明示的に呼ばれます。二重に保護されています。
■ UI_SaveSlot(追加内容)
- Awake で slotButton と deleteButton の UI_ButtonVisual をキャッシュ
- Setup() 内でスロットボタンの状態に応じて SetDisabled() / SetNormal() を呼び出し
- オートスロットのセーブ時のみ SetDisabled()、それ以外は SetNormal()
- デリートボタンは常に SetNormal()(データなし時はGameObject自体が非表示のため不要)

| ボタン | 状態 |
|---|---|
| slotButton(通常) | Normal / Hover / Press |
| slotButton(オートスロット・セーブ時) | Disabled |
| deleteButton | Normal / Hover / Press |
実機での挙動
セーブ時のスクリーンショットで詰まりそうになりましたが、
設定画面のデザイン実装に関してはすんなりと行きました。
「キー操作」「パッド操作」は、まだすべてに対応させていないので見送りです。
キーコンフィグには手を出さないほうが良さそうな感じなので「操作画面」止まりにはなりそうです。
次はメイン画面内のUI?を実装しようと思います。
難題は音源連動のイコライザーになりそうですが、やはり音関係には必須システムですので頑張ります(^ω^)

コメント