UI画面を構築する上で共通事項はできあがっています。
それを踏まえて、音量設定の設計案をAiに考案してもらいます。
Aiに共通事項や既存スクリプトを確認してもらう資料用として、
Unityで、スクリプトの一括ファイルを作成する方法(AI用コンテキスト生成カスタム)も導入してみましたが、
Aiに添付したら文字数が多すぎて、速攻で使用トークンが枯れたのでお勧めしませんw
重要事項の要約をまとめてもらい、かつ文字数も少なくて済む「NotebookLM」を活用したほうが全然良いです。
「API」キーでローカルファイルを指定しない、できない人たちにはこちらがお薦めです。
音量設定の指標
- 音量の種類
・マスターボリューム
・BGM音量
・SE音量
・システム音量
・ボイス音量(将来的実装を見越して。今回は実装しない)
マスター音量はすべての音量の基音量。それ以下は、基音量を基準にしての音量調整になるように。
BGM音量・SE音量・システム音量を分けることは可能なのか。
可能として、その方法は?専用のフォルダを作成?音素材をラベルなどで識別?
- 音量管理の仕組み
業界標準・推奨ということなので「AudioMixer」を使用して構築していきたい。
- 保存方法
テキスト設定と同じくSys_フラグ(絶対変数)で永久保存。
- UI操作感
・スライダーで0〜100の数値調整(テキスト設定と同じ方式):同じく数値表示もつける。
・ミュートボタンをつける。
・プレビュー再生(スライダーを動かすと音が鳴る)をつける:テスト音は制作側が指定可能に。
- その他、スタンダードで考えて、あると便利・ないと不便・大胆な機能などがあれば提案お願いします。
音量設定の設計案
すべての検証を行い、設計案に移ってもらいます。
AudioMixer構造
Unityエディタ上で、以下のMixerGroupを作成します。
SoundMixer (AudioMixer)
└── Master (MixerGroup)
├── BGM (MixerGroup)
├── SE (MixerGroup)
└── Voice (MixerGroup)
Exposed Parametersとして以下の4つを公開します。名前はコードから参照するため正確に定めます。
“MasterVolume“ ”BGMVolume“ ”SEVolume“ ”VoiceVolume“
新規スクリプト構成
■ Sys_AudioSettingsManager.cs
・音量・ミュートの値管理
・AudioMixerへのリアルタイム反映
・Close時の一括保存
メソッド構成は Sys_TextSettingsManager と同じパターンに揃えます。
// リアルタイム反映のみ(保存しない)
public void SetVolumeImmediate(ChannelType channel, int value)
public void SetMuteImmediate(ChannelType channel, bool mute)
// Close時に一括保存
public void SaveAll()
// 初期化(デフォルト値書き込み)
private void InitializeDefaults()
■ UI_AudioSettingsPanel.cs
「UI_PanelBaseを継承します。UI_TextSettingsPanel」と同じ設計パターンです。
Open時にSys_AudioSettingsManagerから現在値を読んでUIに反映、Close時にSaveAll()を呼びます。
スライダーとミュートの連動ロジック
■「マスターボリューム」→「ミュート」「ON」
・スライダー調整でもミュートは解除されない
・表示:BGM・SE・Voice「ミュート」「ON」
・機能:子のミュートボタン操作不可・スライダー操作不可
■ 「BGM」「SE」「Voice」→「ミュート」「ON」
・スライダー調整でもミュートは解除されない
プレビュー再生
・BGMはリアルタイム調整
・SE・Voiceはdelay方式のワンショット再生
・スライダーが動くたびにCoroutineをキャンセル&再起動
「初期設定に戻す」ボタン
UIパネル側のボタンから呼び出し後、スライダーとミュートボタンの表示をRefreshAll()で更新。
Hierarchy構造
[Scene Root]
│
├── [Persistent] ← DontDestroyOnLoadで生き続けるオブジェクト群
│ ├── Sys_Flag_Manager
│ ├── Sys_TextSettingsManager
│ └── Sys_AudioSettingsManager ← 今回追加
│ └── (AudioMixerをInspectorでアサイン)
│
└── UI_Root (Canvas)
├── UI_SaveLoadPanel
├── UI_TextSettingsPanel
└── UI_AudioSettingsPanel ← 今回追加
└── Panel (GameObject, 初期非表示)
├── CloseButton
├── ResetButton
│
├── Master_Section
│ ├── Label (“マスター”)
│ ├── Slider_Master
│ ├── Text_Master (数値表示)
│ └── MuteButton_Master
│
├── BGM_Section
│ ├── Label (“BGM”)
│ ├── Slider_BGM
│ ├── Text_BGM
│ └── MuteButton_BGM
│
├── SE_Section
│ ├── Label (“SE”)
│ ├── Slider_SE
│ ├── Text_SE
│ └── MuteButton_SE
│
└── Voice_Section
├── Label (“ボイス”)
├── Slider_Voice
├── Text_Voice
└── MuteButton_Voice
音量設定の実装
AudioMixerの作成

1. 新規「Audio Mixer」を作成:名前を「SoundMixer」にする
2. 「Audio Mixer」ウィンドウ:Groupsパネルの「Master」を選択し、+ ボタンで子グループ「BGM」を追加
3. 「SE」「Voice」も追加:Masterの子として作ること。BGMの子にならないよう注意

4. 「Expose ‘Volume (of Master)’ to script」を選択:「Master」グループ → Inspectorの Volume 右クリック

5. 「Exposed Parametersリスト」の名前変更:「MasterVolume」
6. 「BGM」「SE」「Voice」もそれぞれ同様に行う:名前は「BGMVolume」「SEVolume」「VoiceVolume」

これで「BGM」「SE」「Voice」が「マスターボリューム」に連動した「Audio Mixer」の完成です。
スクリプトの作成

UI画像専用設定方法:いつものようにManagerはルート直下に。


UIオブジェクトを配置後に、対応する部分にアサインしていきます。
■ previewAudioSourceの設定(重要)
「SE」「Voice」のプレビュー音源用に「AudioSource」を2つ作成しておきます。
今回は分かりやすいように、「SE_Audio_Source」オブジェクト「Voice_Audio_Source」オブジェクトを作り、
それぞれに「AudioSource」コンポーネントを追加しています。
BGM設定

■ AudioSource
・Play On Awake:すぐに音を鳴らしたい場合はチェック。BGMはすぐに鳴らせるのでチェックしておきます。
・Loop:ループさせる場合はチェック。
・Priority:CPU負荷が高い瞬間に再生処理が後回しにされるのを防ぎます。0 (High)にしておきます。
■ Audio Clip(素材の方)
・Decompress On Load:メモリ上に解凍済みの(生の)状態で保持される。
・PreloadAudio Data:シーン開始時にあらかじめメモリに展開される。
■ 低スペックPCでの「安定性」を考える
1. Load Type:Decompress On Load(解凍してロード)
理由:低スペックPCで最も怖いのは「CPUの瞬間的なスパイク(負荷の跳ね上がり)」です。
仕組み:
「Compressed In Memory」は再生中にリアルタイムで解凍するため、常にCPUを少しずつ使い続けます。
「Decompress On Load」はメモリを多く使いますが、再生中のCPU負荷はほぼゼロになります。
判断:今回のBGMは 0.5MB と非常に軽量です。解凍しても数MB程度にしかなりません。
最近の「超ローPC」でもメモリは数GBあるはずなので、数MBのメモリを差し出してCPU負荷を減らす 方が、
動作のガタつき(スタッタリング)を防ぐ意味で圧倒的に有利です。
2. Preload Audio Dat:オン(チェックを入れる)
理由:「音が鳴るべき瞬間に音が鳴らない」のを防ぐためです。
仕組み:
これがオフだと、再生直前にディスク(HDD/SSD)から読み込みを開始します。
低スペックPC、特にHDDを使っている環境では、この読み込み待ちで一瞬ゲームが止まることがあります。
判断:シーン開始時に読み込んでおくことで、ゲームプレイ中のディスクI/O(読み書き負荷)を減らせます。
■ 低スペックPC向け:サウンド設計のガイドライン
| 種類 | 推奨 Load Type | Preload | 理由 |
|---|---|---|---|
| BGM (短い/軽量) | Decompress On Load | ON | CPU負荷を徹底的に排除するため。 |
| SE (効果音全般) | Decompress On Load | ON | 反応速度(レイテンシ)が命。 鳴った瞬間の負荷をゼロにする。 |
| Voice (長いセリフ) | Compressed In Memory | OFF | ボイスは数が多い。 全部メモリに載せるとメモリ不足になるため。 |
| BGM (5分以上の大曲) | Streaming | OFF | メモリ消費を抑えるため。 ディスクから少しずつ読み込む。 |
■ BGMループで「間」が空く原因
MP3特有の無音区間(ヘッダーギャップ)
MP3という規格自体、ファイルの先頭や末尾に「数ミリ秒の無音(ヘッダー情報等)」が強制的に挿入される仕様になっています。どれだけ完璧に波形編集しても、Unityでループさせると必ず「プツッ」とした間やノイズが入ります。
解決方法:「WAV」または「OGG」形式で書き出す・変換する。
実機での挙動
今回は「AudioMixer」という音源専用機能を扱いました。
そこで若干もたつきましたが、おおむねすんなりと実装できたのではないかと思います。
音関連は奥が深そうなので、じっくりといじるターンが楽しみでもあります。
次回は、音実装の流れで提案された「SE再生マネージャー」というものを作ってみようと思います。
またManagerが増えますね…
効果音を設定する際に、ひとつひとつの作業にならないよう管理をしやすくするため、のものらしいです。
「マネージャーで一元管理」
これがUnityでの構築方法なのだと、やっと分かりかけてきています。
プロジェクトまとめ
システム概要
「AudioMixer」を核とし「Sys_Flag_Manager(セーブデータ管理)」と連動させた、永続性のある音量管理システム。
実装済みコンポーネント
■ Sys_AudioSettingsManager.cs
・音量データの保持・反映・保存の司令塔。
・起動時の爆音を防ぐため、1フレーム待機してからMixerへ反映する初期化ロジックを搭載。
・スライダー値(0-100)を対数的なデシベル値(-80dB〜0dB)へ変換。
■ UI_AudioSettingsPanel.cs
・ユーザーインターフェースの制御。
・Masterミュート時に子要素(BGM/SE/Voice)をグレーアウトし操作不能にする排他制御。
・SEとVoiceを別々の「AudioSource」で鳴らすプレビュー機能。
・右クリックでのクイッククローズ対応。
■ SoundMixer (AudioMixer)
・Master / BGM / SE / Voice の階層構造。
・露出パラメータ:MasterVolume・BGMVolume・SEVolume・VoiceVolume
運用上の注意点(備忘録)
・新規SE/Voiceの追加
必ず「AudioSource」の「Output」欄に「Mixer」内の適切なグループ(SEやVoice)をドラッグ&ドロップすること。
これを行わないと、設定画面で音量を下げても「爆音」で鳴り続けます。
・低スペックPCへの配慮
短い音素材は「Decompress On Load(メモリ展開)」に、
長い曲やボイスは「Compressed In Memory」または「Streaming」に設定し、
CPU負荷とメモリ消費のバランスを取ること。
ロード後の挙動と修正箇所
■ 発生していた問題
AudioSourceのMissing参照による音声停止
「Sys_Messenger」が自身にアタッチされた「AudioSource」を直接参照していたため、
セーブ&ロードやシーン遷移時にインスタンスとの紐付けが切れ、ポポポ音・ボイスが鳴らなくなる不具合が発生していた。
■ 解決方針
「再生機」をMessengerから切り離し、常駐Managerに委譲する
Messengerは「AudioClip(音源データ)」のみを保持し、
再生処理はDontDestroyOnLoadで常駐する「Sys_AudioSettingsManager」に一元化。
Messengerがいつ生成・破棄されても再生機は常に安定して動作する。

コメント