【Godot4.x】BGMのクロスフェードサンプル

Godot Engine で BGMのクロスフェードをするサンプルを作ったので公開します。

2025.8.24追記

Godot 4.xの最新バージョンではインタラクティブミュージックの機能が標準で用意されているのでそれを使うのが良さそうです

BGMクロスフェードサンプル

プロジェクトファイル

プロジェクトファイルは以下からダウンロードできます。

使い方

使い方は、BGM管理用のノード (ここでは "Music" ) を作成してその下に "AudioStreamPlayer" を追加します。

そしてBGM管理ノード ("Music") に "InteractiveMusic.gd" をアタッチします。

そしてBGM管理ノードの play() でBGM番号を指定して再生します。

BGM番号はノードの並び順です。

extends Node2D

# 自動で停止するかどうか
# トラックの同期を取る必要がなければ true
const AUTO_STOP = false
# フェード時間.
const FADE_TIME = 2.0

# BGM管理.
@onready var _music = $Music

@onready var _label = $Label
@onready var _label2 = $Label2

func _ready() -> void:
    # あらかじめすべて再生することで同期を取った再生ができる.
    _music.play_all_mute()
    # フェードなしで Idx=0 の BGMを再生.
    _music.play(0, 0, AUTO_STOP)

func _process(delta: float) -> void:
    _label.text = "Track 0 - dB: %3.f %s pos:%3.2f"%[
            _music.get_track_db(0),
            _music.get_track_state_dbg(0),
            _music.get_track_playback_pos(0)]
    _label2.text = "Track 1 - dB: %3.f %s pos:%3.2f"%[
            _music.get_track_db(1),
            _music.get_track_state_dbg(1),
            _music.get_track_playback_pos(1)]

func _on_button_pressed() -> void:
    # フェードありで Idx=0 の BGMを再生.
    _music.play(0, FADE_TIME, AUTO_STOP)

func _on_button_2_pressed() -> void:
    # フェードありで Idx=1 の BGMを再生.
    _music.play(1, FADE_TIME, AUTO_STOP)

なお、play_all_mute() で最初にすべてのBGMを再生したり、AUTO_STOPfalse にしているのは、2つのBGMを同時に再生することで同期を取ったクロスフェードができるためです。

具体的には、今回の2つのBGMはリズム部分や音の印象を変えただけでフレーズそのものは同じです。

そのため再生位置をそろえることで、スムーズにクロスフェードできるようになっています。

このようにフレーズの途中でクロスフェードすることができます。

ただ、このような同期が不要であれば、play_all_mute() は使わなくても問題ありません。

参考

今回の記事を書くにあたって、以下のアドオンを参考にしました。

関連記事

関連するBGM周りの記事は以下のものとなります。