【Godot】Godotオーディオ管理の基礎: AudioStreamPlayerとAudio Busを使いこなす

作成: 2025-12-10最終更新: 2025-12-16

AudioStreamPlayerとAudio Busの使い方を解説。BGM/SE管理と音量制御のベストプラクティス。

概要

ゲーム開発において、サウンドはプレイヤーの体験を大きく左右する重要な要素です。Godot EngineでBGMや効果音(SE)を扱う際、「音が途切れる」「音量調整が面倒」といった課題に直面することがあります。

この記事では、Godotのオーディオ管理の核となる AudioStreamPlayerAudio Bus の基本から、シングルトンによる実践的な管理方法まで解説します。


Godotオーディオシステムの三大要素

要素役割アナロジー
AudioStream音声データそのものCDやMP3ファイル
AudioStreamPlayer音を再生するノードCDプレイヤー
Audio Bus音の信号を束ねて制御する経路ミキシングコンソール

AudioStreamPlayerの種類

ノード名主な用途特徴
AudioStreamPlayerBGMやUI音など位置情報なし、常に中央から聞こえる
AudioStreamPlayer2D2Dゲームの効果音カメラからの距離や方向で音量・パンが変化
AudioStreamPlayer3D3Dゲームの効果音3D空間での距離減衰・ドップラー効果対応

Audio Bus(オーディオバス)

Audio Busは、再生される音の「通り道」であり、ミキシングコンソールのような役割を持ちます。

  • Master Bus: 全ての音が最終的に通る出力バス
  • カスタムバス: BGM、SE、ボイスなど、種類ごとに作成

主な役割:

  1. 音量の一括制御: バス単位でBGM全体、SE全体の音量を調整
  2. エフェクトの適用: リバーブやコンプレッサーを一括適用

よくある間違いとベストプラクティス

よくある間違いベストプラクティス
SE再生に単一ノードを使い回す
音が途切れる
SE再生ごとにノードを動的生成
finishedシグナルでqueue_free()して破棄。またはmax_polyphonyプロパティで同一ノードでの重複再生を許可する方法もある。
バスを分けずに個別ノードで音量調整
コードが煩雑に
音の種類ごとにAudio Busを分割
「BGM」「SFX」「Voice」でバス管理
バスのインデックスをハードコーディングバス名でインデックスを取得
AudioServer.get_bus_index("BGM")

効果音(SE)の正しい再生方法

# ベストプラクティス: ノードを動的生成して再生後削除
func play_sfx(sfx_stream: AudioStream):
    var player = AudioStreamPlayer.new()
    player.stream = sfx_stream
    player.bus = "SFX"
    add_child(player)
    player.play()
    player.finished.connect(func(): player.queue_free())

# 使い方
var attack_sfx = preload("res://assets/sfx/attack.ogg")
play_sfx(attack_sfx)

2D/3Dゲームの場合: 位置を持たせたい場合は AudioStreamPlayer2D または AudioStreamPlayer3D を使用し、global_position を設定してください。


実践: シングルトンによるオーディオ管理

ゲーム全体のオーディオを統括するAudioManagerシングルトンを作成すると、どのシーンからでも簡単に音を制御できます。

プロジェクト設定:

  1. 「プロジェクト」→「プロジェクト設定」→「AutoLoad」タブ
  2. AudioManager.gdを追加
# AudioManager.gd
extends Node

const BGM_BUS_NAME = "BGM"
const SFX_BUS_NAME = "SFX"

@onready var bgm_bus_index = AudioServer.get_bus_index(BGM_BUS_NAME)
@onready var sfx_bus_index = AudioServer.get_bus_index(SFX_BUS_NAME)

var bgm_player: AudioStreamPlayer

func _ready():
    if bgm_bus_index == -1:
        push_error("Audio Bus '%s' not found." % BGM_BUS_NAME)
    if sfx_bus_index == -1:
        push_error("Audio Bus '%s' not found." % SFX_BUS_NAME)

# BGMを再生(フェードイン付き)
func play_bgm(stream: AudioStream, fade_in_duration: float = 0.5):
    if not bgm_player:
        bgm_player = AudioStreamPlayer.new()
        bgm_player.bus = BGM_BUS_NAME
        add_child(bgm_player)

    bgm_player.stream = stream
    bgm_player.volume_db = -80.0
    bgm_player.play()

    var tween = create_tween()
    tween.tween_property(bgm_player, "volume_db", 0.0, fade_in_duration)

# 効果音を再生
func play_sfx(stream: AudioStream, position: Vector2 = Vector2.ZERO):
    var player: Node
    if position == Vector2.ZERO:
        player = AudioStreamPlayer.new()
    else:
        player = AudioStreamPlayer2D.new()
        player.global_position = position

    player.stream = stream
    player.bus = SFX_BUS_NAME
    add_child(player)
    player.play()
    player.finished.connect(func(): player.queue_free())

# BGMの音量を設定 (0.0 - 1.0)
func set_bgm_volume(linear_volume: float):
    if bgm_bus_index == -1:
        return
    AudioServer.set_bus_volume_db(bgm_bus_index, linear_to_db(clampf(linear_volume, 0.0, 1.0)))

# SFXの音量を設定 (0.0 - 1.0)
func set_sfx_volume(linear_volume: float):
    if sfx_bus_index == -1:
        return
    AudioServer.set_bus_volume_db(sfx_bus_index, linear_to_db(clampf(linear_volume, 0.0, 1.0)))

呼び出し例:

# player.gd
const JUMP_SOUND = preload("res://assets/sfx/jump.ogg")

func _process(delta):
    if Input.is_action_just_pressed("jump"):
        AudioManager.play_sfx(JUMP_SOUND, global_position)

パフォーマンスと代替パターン

大量のSEが同時に発生する場合の選択肢:

アプローチメリットデメリット適した状況
動的インスタンス化実装がシンプル大量生成時にノード生成コストほとんどのゲーム
オブジェクトプールパフォーマンスが安定実装が複雑毎秒数十〜数百のSEが鳴るゲーム

まずは動的インスタンス化から始め、プロファイリングでボトルネックが判明した場合にのみプールを検討するのが賢明です。

Audio Busへのエフェクト適用

バスにエフェクトを追加すると、そのバスを通る全ての音に一括で効果を適用できます。

  1. エディタ下部の「オーディオ」タブを開く
  2. エフェクトをかけたいバス(例: SFX)を選択
  3. 「エフェクトの追加」から AudioEffectReverb を選択
  4. Room SizeWet などを調整

これで洞窟や大聖堂のような残響を簡単に表現できます。

まとめ

概念役割ベストプラクティス
AudioStreamPlayer音を鳴らすノードSEは動的生成、BGMはシーンに固定配置
Audio BusミキシングコンソールBGM/SE/Voiceでバスを分けて管理
シングルトン一元管理AudioManagerで全体を統括

次のステップ:

  1. Audio Bus Layoutの永続化: audio_bus_layout.tresとして保存
  2. BGMのループ設定: .oggファイルのインポート設定で「Loop」を有効にする
  3. AudioStreamPlayer2D/3Dの深掘り: 空間的な音の減衰やパンニング
  4. 高度なエフェクトチェーン: EQ → Compressor → Limiter