xiandie/manager/audio_manager/vibe_group_player.gd

90 lines
2.7 KiB
GDScript3
Raw Normal View History

2025-06-25 17:53:16 +00:00
@tool
class_name VibeGroupPlayer
extends Node
var vibe_group: VibeGroup
var _base_player: AudioStreamPlayer
var _embellishment_players = [] as Array[AudioStreamPlayer]
var _embellishment_timers = [] as Array[Timer]
func _init(group: VibeGroup):
vibe_group = group
# 初始化基础播放器
_base_player = AudioStreamPlayer.new()
_base_player.name = "BasePlayer"
_base_player.bus = "game_sfx"
_base_player.stream = group.base_sound
_base_player.volume_db = group.group_db + group.base_sound_db
# 循环播放
if vibe_group.base_sound.get_length() > 0:
_base_player.finished.connect(_base_player.play)
add_child(_base_player)
_embellishment_players.resize(group.embellishments.size())
_embellishment_timers.resize(group.embellishments.size())
# 初始化点缀音播放器池
for i in range(group.embellishments.size()):
if group.embellishments[i] == null:
continue
var player = AudioStreamPlayer.new()
player.name = "EPlayer" + str(i)
player.bus = "game_sfx"
player.stream = group.embellishments[i].sound
add_child(player)
_embellishment_players.append(player)
var timer = Timer.new()
timer.one_shot = true
timer.name = "ETimer" + str(i)
timer.autostart = false
add_child(timer)
_embellishment_timers.append(timer)
timer.timeout.connect(_on_embellishment_timer_timeout.bind(i))
func _on_embellishment_timer_timeout(id: int):
var embellishment = vibe_group.embellishments[id] as Embellishment
if not embellishment:
return
var player = _embellishment_players[id] as AudioStreamPlayer
var timer = _embellishment_timers[id] as Timer
# 增加随机性
timer.wait_time = randf_range(embellishment.min_interval, embellishment.max_interval)
timer.start()
player.volume_db = (vibe_group.group_db + embellishment.db) * randf_range(0.8, 1.2)
player.pitch_scale = randf_range(0.8, 1.2)
player.play()
func _ready():
if Engine.is_editor_hint():
return
func play():
_base_player.play()
# 设置并启动所有点缀音的计时器
for i in range(vibe_group.embellishments.size()):
var embellishment = vibe_group.embellishments[i]
if not is_instance_valid(embellishment) or not is_instance_valid(embellishment.sound):
continue
var timer = _embellishment_timers[i]
# 如果 loop则 min_interval 与 max_interval 无效
if embellishment.loop:
var player = _embellishment_players[i]
player.volume_db = vibe_group.group_db + embellishment.db
if player.stream:
player.play()
player.finished.connect(player.play)
else:
# 首次启动计时器
var random_wait_time = randf_range(
embellishment.min_interval, embellishment.max_interval
)
timer.start(random_wait_time)
func stop_and_free():
if not is_queued_for_deletion():
queue_free()