124 lines
3.1 KiB
GDScript
124 lines
3.1 KiB
GDScript
@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 切换为 always,ease 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
|