xiandie/scene/entity/audio/sfx2d.gd
2025-07-03 17:51:21 +08:00

78 lines
1.8 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@tool
class_name Sfx2D extends AudioStreamPlayer2D
@export var loop := false
# 0 一个接一个循环; >0 则每 loop_round_time 播放一次
@export var loop_round_time := 0.0
@export var debug_play := false:
set(val):
debug_play = false
if not Engine.is_editor_hint() or not is_node_ready():
return
if loop_round_time > 0.0:
timer.wait_time = loop_round_time
timer.start()
else:
timer.stop()
play()
var timer: Timer
func _ready() -> void:
bus = &"game_sfx"
process_mode = Node.PROCESS_MODE_PAUSABLE
if Engine.is_editor_hint():
return
timer = Timer.new()
timer.autostart = autoplay and loop and loop_round_time > 0.0 and not Engine.is_editor_hint()
timer.one_shot = false
timer.wait_time = max(0.1, loop_round_time)
timer.timeout.connect(_on_timer_timeout)
add_child(timer)
finished.connect(_on_finished)
# ground 退出时process mode 切换为 alwaysease out
SceneManager.ground_transition_pre_paused.connect(_on_ground_transition_pre_paused)
func _on_ground_transition_pre_paused():
if not playing:
return
print("[GroundTransition] Sfx2D %s ease killing..." % name)
easing_kill(1.0)
func _on_timer_timeout() -> void:
if not loop or loop_round_time <= 0.0:
timer.stop()
return
play()
func _on_finished() -> void:
if not loop:
timer.stop()
else:
if loop_round_time <= 0:
timer.stop()
play()
else:
timer.start(loop_round_time)
# queue free 导致 sfx 无法播放,使用全局声源
func global_play() -> void:
if stream:
AudioManager.play_sfx(stream)
# 注意:会导致 volume db 变化
func easing_kill(duration: float = 2.0) -> void:
# stop with easing
if playing:
var tween = create_tween()
tween.bind_node(self)
tween.tween_property(self, "volume_linear", 0.0, duration)
tween.tween_callback(stop)