godot-plateformer/addons/reedfx/sfx/SFXManager.gd

91 lines
2.6 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.

'''音效播放管理器
可以通過預設的音效表和對應Node的Signal播放對應的音效
'''
class_name ReedSFXManager extends Node
@export var bindings: Array[SFXSignalBinding] = []
@export var enable_debug: bool = true
func _ready() -> void:
_bind_all()
func _bind_all() -> void:
print("[SFX] binding count =", bindings.size(), " manager path=", get_path())
for binding in bindings:
print("[SFX] try bind: target_node=", binding.target_node, " signal=", binding.signal_name)
if not has_node(binding.target_node):
push_warning("[SFX] target node not found: %s (manager=%s)" % [binding.target_node, get_path()])
continue
var target := get_node(binding.target_node)
print("[SFX] target resolved:", target, " path=", target.get_path())
if not target.has_signal(binding.signal_name):
push_warning("[SFX] signal not found: %s on %s" % [binding.signal_name, target.get_path()])
continue
# 🔥 关键lambda 包一层 + 打印确认
var cb := func(ctx = null):
print("[SFX] callback fired! binding=", binding, " ctx=", ctx)
_on_sfx_signal(binding, ctx)
# 防止重复连接
if target.is_connected(binding.signal_name, cb):
print("[SFX] already connected, skip:", binding.signal_name)
else:
var err := target.connect(binding.signal_name, cb)
print("[SFX] connect result =", err, " (OK=0)")
func _on_sfx_signal(binding: SFXSignalBinding, args: Variant) -> void:
if enable_debug and binding.debug_print:
print_debug(binding.get_debug_message())
match binding.spawn_space:
SFXSignalBinding.SpawnSpace.GLOBAL:
_play_global(binding)
SFXSignalBinding.SpawnSpace.WORLD_POSITION:
if args is Dictionary and args.has("world_pos"):
_play_at_position(binding, args["world_pos"])
# -----------------------------
# 播放逻辑
# -----------------------------
func _play_global(binding: SFXSignalBinding) -> void:
var target := get_node(binding.target_node)
if not binding.audio_stream:
return
var player := _create_player(binding)
add_child(player)
player.global_position = target.global_position + binding.offset
if binding.autoplay:
player.play()
func _play_at_position(binding: SFXSignalBinding, pos: Vector2) -> void:
if not binding.audio_stream:
return
var player := _create_player(binding)
add_child(player)
player.global_position = pos + binding.offset
if binding.autoplay:
player.play()
func _create_player(binding: SFXSignalBinding) -> AudioStreamPlayer2D:
var player := AudioStreamPlayer2D.new()
player.stream = binding.audio_stream
player.volume_db = binding.volume_db
player.pitch_scale = binding.pitch_scale
player.finished.connect(player.queue_free)
return player