90 lines
2.7 KiB
GDScript3
90 lines
2.7 KiB
GDScript3
|
@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()
|