xiandie/manager/audio_manager/audio_manager.gd
2025-06-26 01:53:16 +08:00

118 lines
3.3 KiB
GDScript

@tool
extends Node
var vibe_group_collection := preload("uid://bfhwn1v0c2io7") as VibeGroupCollection
@export_tool_button("重载vibe groups") var reload_groups = _reload_groups
static var VIBE_GROUPS := [] as Array[String]
# random players
var sfx_players = [] as Array[AudioStreamPlayer]
var sfx_players_idx = 0
# bgm player
var bgm_dict = {}
# vibe player
func _ready() -> void:
for i in range(5):
var sfx_player = RandomAudioStreamPlayer.new()
sfx_players.append(sfx_player)
sfx_player.bus = "game_sfx"
add_child(sfx_player)
if Engine.is_editor_hint():
_reload_groups()
func _reload_groups():
VIBE_GROUPS.clear()
for group in vibe_group_collection.groups:
if group and group.group_name:
VIBE_GROUPS.append(group.group_name)
else:
printerr("VibeGroup has no name: ", group)
func play_sfx(sfx: AudioStream, db := 1.0) -> void:
sfx_players[sfx_players_idx].stream = sfx
sfx_players[sfx_players_idx].volume_db = db
sfx_players[sfx_players_idx].play()
sfx_players_idx = wrapi(sfx_players_idx + 1, 0, 5)
# 挂载并循环播放 bgm 音效
func loop_bgm_music(music_name: StringName, stream: AudioStream, db := 0.0, loop := true) -> void:
var audio_player = bgm_dict.get(music_name) as AudioStreamPlayer
if audio_player:
if audio_player.playing:
print("bgm music is already playing: ", music_name)
return
bgm_dict.erase(music_name)
audio_player.stop()
audio_player.queue_free()
audio_player = AudioStreamPlayer.new()
add_child(audio_player)
bgm_dict[music_name] = audio_player
audio_player.stream = stream
audio_player.volume_db = db
audio_player.bus = "game_sfx"
audio_player.play()
if loop and stream.get_length() > 0:
audio_player.finished.connect(audio_player.play)
func stop_bgm_music(music_name: StringName, ease_duration := 3.0) -> void:
var audio_player = bgm_dict.get(music_name) as AudioStreamPlayer
if audio_player:
if ease_duration <= 0:
remove_child(audio_player)
audio_player.queue_free()
else:
var tween = create_tween()
tween.tween_property(audio_player, "volume_db", -80.0, ease_duration)
tween.tween_callback(audio_player.queue_free)
bgm_dict.erase(music_name)
else:
print("music bgm not found: ", music_name)
#### vibe management
## 负责实际创建 AudioStreamPlayer 节点并播放、管理 VibeGroup。
# 当前正在播放的音轨组资源
var vibe_player_dict:Dictionary[StringName,VibeGroupPlayer] = {}
func _find_group_by_name(group_name: StringName) -> VibeGroup:
for group in vibe_group_collection.groups:
if group.group_name == group_name:
return group
return null
## 核心方法:播放一个指定的 VibeGroup
func play_group(group_name: StringName):
var group = _find_group_by_name(group_name)
if not is_instance_valid(group):
printerr("VibeManager: VibeGroup is not valid. group_name:", group_name)
return
# 如果请求播放的是当前已在播放的组,则忽略
if vibe_player_dict.has(group_name):
return
var vibe_player = VibeGroupPlayer.new(group)
vibe_player.name = group_name
add_child(vibe_player)
vibe_player_dict[group_name] = vibe_player
vibe_player.play()
func stop_group(group_name: StringName):
if is_queued_for_deletion():
return
if not vibe_player_dict.has(group_name):
return
var vibe_player = vibe_player_dict[group_name]
vibe_player_dict.erase(group_name)
remove_child(vibe_player)
vibe_player.stop_and_free()