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

124 lines
3.1 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 Sfx extends AudioStreamPlayer
@export_enum("交互与效果音", "BGM", "场景背景音") var mode := "交互与效果音":
set(value):
mode = value
notify_property_list_changed()
# 当前播放状态注册;节点销毁前卸载
# TODO BGM 过程抑制场景音效;场景音效随玩家运动呼吸 (结合 Sfx2D)
# 感应玩家移动:装饰音
var default_db := 0.0
# 只有 场景背景音 生效
var scene_loop := true
var scene_autostart := true
var scene_sense_player_mov := false
func _ready() -> void:
bus = &"game_sfx"
default_db = volume_db
process_mode = Node.PROCESS_MODE_INHERIT
if Engine.is_editor_hint():
return
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] Sfx %s ease killing..." % name)
easing_kill(1.0)
func _on_finished() -> void:
if mode == "场景背景音" and scene_loop:
play()
func resart(ease_duration := 1.0):
easing_kill(ease_duration).tween_callback(play)
# queue free 导致 sfx 无法播放,使用全局声源
func global_play() -> void:
if stream:
AudioManager.play_sfx(stream)
# 注意:会导致 volume db 变化
func easing_kill(duration: float = 2.0) -> Tween:
# stop with easing
var tween = create_tween()
tween.bind_node(self)
if playing:
tween.tween_property(self, "volume_linear", 0.0, duration)
tween.tween_callback(stop)
# set volume_db back to default
tween.tween_callback(func(): volume_db = default_db)
return tween
func _get_property_list() -> Array[Dictionary]:
if mode != "场景背景音":
return []
# # 只有 场景背景音 生效
# var scene_loop := true
# var scene_autostart := true
# var scene_sense_player_mov := false
return [
{
"name": "场景背景音配置项",
"type": TYPE_NIL,
"usage": PROPERTY_USAGE_GROUP,
},
{"name": "自动开始", "type": TYPE_BOOL},
{"name": "循环播放", "type": TYPE_BOOL},
{"name": "感应玩家操作", "type": TYPE_BOOL}
]
func _property_can_revert(property: StringName) -> bool:
return property == "自动开始" or property == "循环播放" or property == "感应玩家操作"
func _property_get_revert(property: StringName) -> Variant:
if property == "自动开始" or property == "循环播放":
return true
elif property == "感应玩家操作":
return false
return null
func _set(property: StringName, value: Variant) -> bool:
if mode != "场景背景音":
return false
if property == "自动开始":
if value != null:
autoplay = value
scene_autostart = value
return true
elif property == "循环播放":
scene_loop = value
return true
elif property == "感应玩家操作":
scene_sense_player_mov = value
return true
return false
func _get(property: StringName) -> Variant:
if mode != "场景背景音":
return null
if property == "自动开始":
return scene_autostart
elif property == "循环播放":
return scene_loop
elif property == "感应玩家操作":
return scene_sense_player_mov
return null