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]
|
2025-07-03 09:49:00 +00:00
|
|
|
|
var _base_db := 0.0:
|
|
|
|
|
set(val):
|
|
|
|
|
_base_db = val
|
|
|
|
|
_base_player.volume_db = val
|
2025-06-25 17:53:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2025-07-03 09:49:00 +00:00
|
|
|
|
_refresh_base_player_db()
|
2025-06-25 17:53:16 +00:00
|
|
|
|
# 循环播放
|
|
|
|
|
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()
|
2025-07-03 09:49:00 +00:00
|
|
|
|
player.volume_db = _base_db + (vibe_group.group_db + embellishment.db) * randf_range(0.8, 1.2)
|
2025-06-25 17:53:16 +00:00
|
|
|
|
player.pitch_scale = randf_range(0.8, 1.2)
|
|
|
|
|
player.play()
|
|
|
|
|
|
|
|
|
|
|
2025-07-03 09:49:00 +00:00
|
|
|
|
func _refresh_base_player_db() -> void:
|
|
|
|
|
_base_player.volume_db = _base_db + vibe_group.group_db + vibe_group.base_sound_db
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _refresh_embellishment_player_db(id: int) -> void:
|
|
|
|
|
if _embellishment_players[id] == null:
|
2025-06-25 17:53:16 +00:00
|
|
|
|
return
|
2025-07-03 09:49:00 +00:00
|
|
|
|
_embellishment_players[id].volume_db = (
|
|
|
|
|
_base_db + vibe_group.group_db + vibe_group.embellishments[id].db
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func set_volume_linear(volume: float):
|
|
|
|
|
_base_db = linear_to_db(volume)
|
|
|
|
|
for i in range(vibe_group.embellishments.size()):
|
|
|
|
|
_refresh_embellishment_player_db(i)
|
|
|
|
|
_refresh_base_player_db()
|
2025-06-25 17:53:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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]
|
2025-07-03 09:49:00 +00:00
|
|
|
|
_refresh_embellishment_player_db(i)
|
2025-06-25 17:53:16 +00:00
|
|
|
|
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()
|