From 301ee98c0f8e1832ecdede31b0d49f39b983996d Mon Sep 17 00:00:00 2001 From: cakipaul Date: Fri, 18 Jul 2025 19:52:49 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20sfx=5Fconfig=5Fpanel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manager/archive_manager/debug_panel.gd | 43 ++ manager/archive_manager/debug_panel.gd.uid | 1 + manager/archive_manager/debug_panel.tscn | 60 +++ manager/archive_manager/savings_panel.gd | 34 +- manager/archive_manager/savings_panel.tscn | 54 +- manager/archive_manager/sfx_config_panel.gd | 461 ++++++++++++++++++ .../archive_manager/sfx_config_panel.gd.uid | 1 + manager/archive_manager/sfx_config_panel.tscn | 62 +++ manager/scene/scene_manager.gd | 4 +- project.godot | 2 +- scene/ground/ground_loader.gd | 7 + scene/main.gd | 2 +- util/audio_loader.gd | 258 ++++++++++ util/audio_loader.gd.uid | 1 + 14 files changed, 919 insertions(+), 71 deletions(-) create mode 100644 manager/archive_manager/debug_panel.gd create mode 100644 manager/archive_manager/debug_panel.gd.uid create mode 100644 manager/archive_manager/debug_panel.tscn create mode 100644 manager/archive_manager/sfx_config_panel.gd create mode 100644 manager/archive_manager/sfx_config_panel.gd.uid create mode 100644 manager/archive_manager/sfx_config_panel.tscn create mode 100644 util/audio_loader.gd create mode 100644 util/audio_loader.gd.uid diff --git a/manager/archive_manager/debug_panel.gd b/manager/archive_manager/debug_panel.gd new file mode 100644 index 00000000..a0bf282a --- /dev/null +++ b/manager/archive_manager/debug_panel.gd @@ -0,0 +1,43 @@ +extends CanvasLayer + +@onready var quit_debug_button: Button = %QuitDebugModeButton + + +func _ready() -> void: + AudioManager.process_mode = Node.PROCESS_MODE_PAUSABLE + SceneManager.toggle_pause_counter(true, "debugging") + layer = GlobalConfig.CANVAS_LAYER_SETTINGS + quit_debug_button.pressed.connect(_on_quit_debug_button_pressed) + + # 恢复上次打开的 tab + var tab = ArchiveManager.get_global_value(&"debug_panel_tab", 0) + %TabContainer.current_tab = tab + + +func _input(event: InputEvent) -> void: + if ( + event.is_action_pressed("debugging") + or event.is_action_pressed("cancel") + or event.is_action_pressed("escape") + ): + get_viewport().set_input_as_handled() + quit() + + +func _on_quit_debug_button_pressed() -> void: + # 不写入配置 + GlobalConfig.DEBUG = false + quit() + + +func _exit_tree() -> void: + AudioManager.process_mode = Node.PROCESS_MODE_ALWAYS + SceneManager.toggle_pause_counter(false, "debugging") + + +func quit() -> void: + queue_free() + + +func _on_tab_container_tab_changed(tab: int) -> void: + ArchiveManager.set_global_entry(&"debug_panel_tab", tab) diff --git a/manager/archive_manager/debug_panel.gd.uid b/manager/archive_manager/debug_panel.gd.uid new file mode 100644 index 00000000..4344745e --- /dev/null +++ b/manager/archive_manager/debug_panel.gd.uid @@ -0,0 +1 @@ +uid://d3aitlnh5hrfc diff --git a/manager/archive_manager/debug_panel.tscn b/manager/archive_manager/debug_panel.tscn new file mode 100644 index 00000000..b14e95c0 --- /dev/null +++ b/manager/archive_manager/debug_panel.tscn @@ -0,0 +1,60 @@ +[gd_scene load_steps=5 format=3 uid="uid://d4jeeteyq8kk3"] + +[ext_resource type="PackedScene" uid="uid://bo4f3sdubdp61" path="res://manager/archive_manager/savings_panel.tscn" id="1_fbybo"] +[ext_resource type="Script" uid="uid://d3aitlnh5hrfc" path="res://manager/archive_manager/debug_panel.gd" id="1_k0pa6"] +[ext_resource type="PackedScene" uid="uid://b6ogrp5ec5nr3" path="res://manager/archive_manager/sfx_config_panel.tscn" id="2_t7mby"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_k0pa6"] +bg_color = Color(0, 0, 0, 1) + +[node name="DebugLayer" type="CanvasLayer"] +process_mode = 3 +scale = Vector2(0.5, 0.5) +transform = Transform2D(0.5, 0, 0, 0.5, 0, 0) +script = ExtResource("1_k0pa6") + +[node name="PanelContainer" type="PanelContainer" parent="."] +offset_left = 68.0 +offset_top = 28.0 +offset_right = 1068.0 +offset_bottom = 606.0 +theme_override_styles/panel = SubResource("StyleBoxFlat_k0pa6") + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_font_sizes/font_size = 18 +text = "Debug 面板" +horizontal_alignment = 1 + +[node name="QuitDebugModeButton" type="Button" parent="PanelContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "关闭 Debug 模式" + +[node name="TabContainer" type="TabContainer" parent="PanelContainer/VBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(1000, 0) +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +mouse_filter = 0 +current_tab = 0 + +[node name="存档控制" parent="PanelContainer/VBoxContainer/TabContainer" instance=ExtResource("1_fbybo")] +unique_name_in_owner = true +layout_mode = 2 + +[node name="音效控制" parent="PanelContainer/VBoxContainer/TabContainer" instance=ExtResource("2_t7mby")] +unique_name_in_owner = true +visible = false +layout_mode = 2 +metadata/_tab_index = 1 + +[connection signal="tab_changed" from="PanelContainer/VBoxContainer/TabContainer" to="." method="_on_tab_container_tab_changed"] diff --git a/manager/archive_manager/savings_panel.gd b/manager/archive_manager/savings_panel.gd index 5051a041..6ab93c7d 100644 --- a/manager/archive_manager/savings_panel.gd +++ b/manager/archive_manager/savings_panel.gd @@ -1,7 +1,6 @@ extends Control # UI References -@onready var quit_debug_button: Button = %QuitDebugModeButton @onready var archive_grid: GridContainer = %ArchiveGrid @onready var scroll_container: ScrollContainer = %ScrollContainer @onready var current_archive_label: Label = %CurrentArchiveLabel @@ -18,11 +17,9 @@ var next_available_id: int = 2 # Start from 2 since 1 is reserved for main arch func _ready() -> void: - get_parent().layer = GlobalConfig.CANVAS_LAYER_SETTINGS # Setup UI archive_grid.columns = GRID_COLUMNS # Connect signals - quit_debug_button.pressed.connect(_on_quit_debug_button_pressed) save_button.pressed.connect(_on_save_button_pressed) refresh_button.pressed.connect(_refresh_archive_list) name_input.text_submitted.connect(_on_name_submitted) @@ -57,12 +54,6 @@ func _on_name_submitted(_text: String) -> void: _on_save_button_pressed() -func _on_quit_debug_button_pressed() -> void: - # 不写入配置 - GlobalConfig.DEBUG = false - quit() - - func _on_save_button_pressed() -> void: # Check limit if manual_archives.size() >= MAX_MANUAL_ARCHIVES: @@ -152,7 +143,7 @@ func _copy_current_archive(archive_name: String) -> void: func _refresh_archive_list() -> void: - # refresh savings name + # refresh debugging name _update_default_name() # Clear existing items @@ -289,26 +280,3 @@ func _load_manual_archives_data() -> void: func _show_notification(message: String) -> void: SceneManager.pop_notification(message) - - -func _enter_tree() -> void: - SceneManager.toggle_pause_counter(true, "savings") - - -func _exit_tree() -> void: - SceneManager.toggle_pause_counter(false, "savings") - - -func quit() -> void: - queue_free() - - -func _unhandled_input(event: InputEvent) -> void: - # savings 界面接受所有输入事件 - get_viewport().set_input_as_handled() - if ( - event.is_action_pressed("savings") - or event.is_action_pressed("cancel") - or event.is_action_pressed("escape") - ): - quit() diff --git a/manager/archive_manager/savings_panel.tscn b/manager/archive_manager/savings_panel.tscn index 053547bb..adbf52fa 100644 --- a/manager/archive_manager/savings_panel.tscn +++ b/manager/archive_manager/savings_panel.tscn @@ -1,85 +1,71 @@ -[gd_scene load_steps=2 format=3 uid="uid://d4jeeteyq8kk3"] +[gd_scene load_steps=2 format=3 uid="uid://bo4f3sdubdp61"] [ext_resource type="Script" uid="uid://cirf1nw72l315" path="res://manager/archive_manager/savings_panel.gd" id="1_oo2ip"] -[node name="SavingsLayer" type="CanvasLayer"] - -[node name="TestArchivePanel" type="PanelContainer" parent="."] -process_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = 59.0 -offset_top = 21.0 -offset_right = 395.0 -offset_bottom = 262.0 -grow_horizontal = 2 -grow_vertical = 2 -scale = Vector2(0.5, 0.5) +[node name="存档控制" type="PanelContainer"] +offset_right = 405.0 +offset_bottom = 531.0 +mouse_filter = 1 script = ExtResource("1_oo2ip") +metadata/_tab_index = 0 -[node name="VBoxContainer" type="VBoxContainer" parent="TestArchivePanel"] +[node name="VBoxContainer" type="VBoxContainer" parent="."] layout_mode = 2 -[node name="HBoxContainer" type="HBoxContainer" parent="TestArchivePanel/VBoxContainer"] +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] layout_mode = 2 -[node name="Title" type="Label" parent="TestArchivePanel/VBoxContainer/HBoxContainer"] +[node name="Title" type="Label" parent="VBoxContainer/HBoxContainer"] layout_mode = 2 size_flags_horizontal = 3 theme_override_font_sizes/font_size = 24 text = "存档测试管理器(测试专用)" horizontal_alignment = 1 -[node name="QuitDebugModeButton" type="Button" parent="TestArchivePanel/VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -text = "关闭 Debug 模式" - -[node name="存档管理" type="VBoxContainer" parent="TestArchivePanel/VBoxContainer"] +[node name="存档管理" type="VBoxContainer" parent="VBoxContainer"] layout_mode = 2 theme_override_constants/separation = 10 -[node name="CurrentArchiveLabel" type="Label" parent="TestArchivePanel/VBoxContainer/存档管理"] +[node name="CurrentArchiveLabel" type="Label" parent="VBoxContainer/存档管理"] unique_name_in_owner = true layout_mode = 2 theme_override_colors/font_color = Color(0.7, 0.9, 0.7, 1) text = "当前使用存档:1号存档(主存档)" -[node name="HSeparator" type="HSeparator" parent="TestArchivePanel/VBoxContainer/存档管理"] +[node name="HSeparator" type="HSeparator" parent="VBoxContainer/存档管理"] layout_mode = 2 -[node name="SaveContainer" type="HBoxContainer" parent="TestArchivePanel/VBoxContainer/存档管理"] +[node name="SaveContainer" type="HBoxContainer" parent="VBoxContainer/存档管理"] layout_mode = 2 theme_override_constants/separation = 10 -[node name="NameInput" type="LineEdit" parent="TestArchivePanel/VBoxContainer/存档管理/SaveContainer"] +[node name="NameInput" type="LineEdit" parent="VBoxContainer/存档管理/SaveContainer"] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 placeholder_text = "输入存档名称" -[node name="SaveButton" type="Button" parent="TestArchivePanel/VBoxContainer/存档管理/SaveContainer"] +[node name="SaveButton" type="Button" parent="VBoxContainer/存档管理/SaveContainer"] unique_name_in_owner = true custom_minimum_size = Vector2(120, 0) layout_mode = 2 text = "保存当前进度" -[node name="RefreshButton" type="Button" parent="TestArchivePanel/VBoxContainer/存档管理/SaveContainer"] +[node name="RefreshButton" type="Button" parent="VBoxContainer/存档管理/SaveContainer"] unique_name_in_owner = true custom_minimum_size = Vector2(60, 0) layout_mode = 2 text = "刷新" -[node name="HSeparator2" type="HSeparator" parent="TestArchivePanel/VBoxContainer/存档管理"] +[node name="HSeparator2" type="HSeparator" parent="VBoxContainer/存档管理"] layout_mode = 2 -[node name="Label" type="Label" parent="TestArchivePanel/VBoxContainer/存档管理"] +[node name="Label" type="Label" parent="VBoxContainer/存档管理"] layout_mode = 2 theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1) text = "手动存档列表:" -[node name="ScrollContainer" type="ScrollContainer" parent="TestArchivePanel/VBoxContainer/存档管理"] +[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/存档管理"] unique_name_in_owner = true custom_minimum_size = Vector2(0, 380) layout_mode = 2 @@ -87,7 +73,7 @@ size_flags_vertical = 3 horizontal_scroll_mode = 0 vertical_scroll_mode = 2 -[node name="ArchiveGrid" type="GridContainer" parent="TestArchivePanel/VBoxContainer/存档管理/ScrollContainer"] +[node name="ArchiveGrid" type="GridContainer" parent="VBoxContainer/存档管理/ScrollContainer"] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 diff --git a/manager/archive_manager/sfx_config_panel.gd b/manager/archive_manager/sfx_config_panel.gd new file mode 100644 index 00000000..4b5a7a1d --- /dev/null +++ b/manager/archive_manager/sfx_config_panel.gd @@ -0,0 +1,461 @@ +class_name SfxConfigPanel +extends Control + +# signal config_changed(node_name: String, property: String, value) + +# 面板相关 +@onready var scroll_container: ScrollContainer = %ScrollContainer +@onready var vbox_container: VBoxContainer = %VBoxContainer +@onready var import_button: Button = %ImportButton +@onready var export_button: Button = %ExportButton +# 音频预览播放器 +@onready var preview_player: AudioStreamPlayer = %AudioStreamPlayer +# 文件对话框 +@onready var file_dialog: FileDialog = %FileDialog + +# 数据存储 +var sfx_nodes: Array[Node] = [] +var config_data: Dictionary = {} +var current_scene_name: String = "" + + +func _ready(): + file_dialog.file_selected.connect(_on_file_selected) + import_button.pressed.connect(_on_import_pressed) + export_button.pressed.connect(_on_export_pressed) + # 初始加载 + refresh_sfx_list(SceneManager.get_ground()) + + +# 1. 检测 current_scene 下 Sfx 节点 +func refresh_sfx_list(ground: Ground2D, headless := false): + if not headless: + clear_ui() + sfx_nodes.clear() + current_scene_name = GroundLoader.get_ground_scene_readable_name(ground.scene_name) + find_sfx_nodes(ground) + load_config() + if not headless: + create_ui_items() + +var ignore_class_list = ["Portal2D", "Interactable2D", "Note2D", "Inspectable2D", "Pickable2D", "Npc2D", "Ambush2D"] + +func find_sfx_nodes(node: Node): + var script = node.get_script() + if script: + if script.get_global_name() in ignore_class_list: + return + # if node is Sfx or node is VibeSfx: + if node is Sfx: + if node.has_method("play") and node.get("volume_db") != null and node.get("stream") != null: + sfx_nodes.append(node) + # 递归检查子节点 + for child in node.get_children(): + find_sfx_nodes(child) + +func clear_ui(): + for child in vbox_container.get_children(): + child.queue_free() + +# 2. 在面板生成对应条目,双向绑定 +func create_ui_items(): + for sfx_node in sfx_nodes: + create_sfx_item(sfx_node) + +func create_sfx_item(sfx_node: Node): + var item_container = VBoxContainer.new() + item_container.add_theme_constant_override("separation", 8) + vbox_container.add_child(item_container) + + # 节点名称标签 + var name_label = Label.new() + name_label.text = sfx_node.name + name_label.add_theme_font_size_override("font_size", 14) + item_container.add_child(name_label) + + var controls_hbox = HBoxContainer.new() + controls_hbox.add_theme_constant_override("separation", 10) + item_container.add_child(controls_hbox) + + # 音量滑块 + var volume_vbox = VBoxContainer.new() + controls_hbox.add_child(volume_vbox) + + var volume_label = Label.new() + volume_label.text = "音量 (dB)" + volume_vbox.add_child(volume_label) + + var volume_hbox = HBoxContainer.new() + volume_vbox.add_child(volume_hbox) + + var volume_slider = HSlider.new() + volume_slider.min_value = -60.0 + volume_slider.max_value = 20.0 + volume_slider.step = 0.1 + volume_slider.value = sfx_node.volume_db + volume_slider.custom_minimum_size.x = 200 + volume_hbox.add_child(volume_slider) + + var volume_value_label = Label.new() + volume_value_label.text = str(snapped(sfx_node.volume_db, 0.1)) + volume_value_label.custom_minimum_size.x = 50 + volume_hbox.add_child(volume_value_label) + + # 双向绑定音量 + volume_slider.value_changed.connect(func(value): + sfx_node.volume_db = value + volume_value_label.text = str(snapped(value, 0.1)) + save_node_config(sfx_node.name, "volume_db", value) + ) + + # Stream 信息和控制 + var stream_vbox = VBoxContainer.new() + controls_hbox.add_child(stream_vbox) + + var stream_label = Label.new() + stream_label.text = "音频文件" + stream_vbox.add_child(stream_label) + + var stream_hbox = HBoxContainer.new() + stream_vbox.add_child(stream_hbox) + + var stream_name_label = Label.new() + if sfx_node.stream: + stream_name_label.text = sfx_node.stream.resource_path.get_file() + else: + stream_name_label.text = "无音频文件" + stream_name_label.custom_minimum_size.x = 150 + stream_hbox.add_child(stream_name_label) + + # 预览播放按钮 + var preview_button = Button.new() + preview_button.text = "▶" + preview_button.custom_minimum_size = Vector2(30, 30) + preview_button.pressed.connect(func(): preview_audio(sfx_node)) + stream_hbox.add_child(preview_button) + + # 3. 上传文件按钮 + var upload_button = Button.new() + upload_button.text = "上传音频" + upload_button.pressed.connect(func(): open_file_dialog(sfx_node, stream_name_label)) + stream_hbox.add_child(upload_button) + + # 分割线 + var separator = HSeparator.new() + item_container.add_child(separator) + + # 存储节点引用用于后续操作 + item_container.set_meta("sfx_node", sfx_node) + item_container.set_meta("stream_label", stream_name_label) + +func preview_audio(sfx_node: Node): + if sfx_node.stream: + preview_player.stream = sfx_node.stream + preview_player.volume_db = sfx_node.volume_db + preview_player.play() + +var current_upload_node: Node +var current_stream_label: Label + +func open_file_dialog(sfx_node: Node, stream_label: Label): + current_upload_node = sfx_node + current_stream_label = stream_label + file_dialog.popup_centered() + +func _on_file_selected(path: String): + if not current_upload_node: + return + + copy_and_load_audio_file(path, current_upload_node, current_stream_label) + +# 3. 复制文件并加载 +func copy_and_load_audio_file(source_path: String, sfx_node: Node, stream_label: Label): + var file_name = source_path.get_file() + var audio_dir = "user://audio/" + current_scene_name + "/" + var target_path = audio_dir + file_name + + # 确保目录存在 + DirAccess.open("user://").make_dir_recursive("audio/" + current_scene_name) + + # 复制文件 + var source_file = FileAccess.open(source_path, FileAccess.READ) + if not source_file: + push_error("无法读取源文件: " + source_path) + return + + var target_file = FileAccess.open(target_path, FileAccess.WRITE) + if not target_file: + push_error("无法创建目标文件: " + target_path) + source_file.close() + return + + target_file.store_buffer(source_file.get_buffer(source_file.get_length())) + source_file.close() + target_file.close() + + # 加载新的音频流 + var new_stream = AudioLoader.new().loadfile(target_path) + if new_stream: + sfx_node.stream = new_stream + stream_label.text = file_name + save_node_config(sfx_node.name, "stream", target_path) + print("音频文件已更新: ", sfx_node.name, " -> ", file_name) + else: + push_error("无法加载音频文件: " + target_path) + +# 4. 配置保存与加载 +func save_node_config(node_name: String, property: String, value): + if not config_data.has(node_name): + config_data[node_name] = {} + config_data[node_name][property] = value + save_config() + +func save_config(): + var config_dir = "user://audio/" + current_scene_name + "/" + DirAccess.open("user://").make_dir_recursive("audio/" + current_scene_name) + + var config_path = config_dir + "audio_config.dat" + var file = FileAccess.open(config_path, FileAccess.WRITE) + if file: + file.store_string(var_to_str(config_data)) + file.close() + +func load_config(): + var config_path = "user://audio/" + current_scene_name + "/audio_config.dat" + var file = FileAccess.open(config_path, FileAccess.READ) + if file: + var config_str = file.get_as_text() + file.close() + config_data = str_to_var(config_str) + if not config_data: + config_data = {} + apply_config() + else: + config_data = {} + +func apply_config(): + for sfx_node in sfx_nodes: + if config_data.has(sfx_node.name): + var node_config = config_data[sfx_node.name] + if node_config.has("volume_db"): + sfx_node.volume_db = node_config["volume_db"] + if node_config.has("stream"): + var stream_path = node_config["stream"] + if FileAccess.file_exists(stream_path): + var new_stream = AudioLoader.new().loadfile(stream_path) + # var new_stream = load(stream_path) + if new_stream: + sfx_node.stream = new_stream + +# 5. Import/Export 功能 +func _on_import_pressed(): + # 打开文件对话框选择导入文件夹或配置文件 + var import_dialog = FileDialog.new() + import_dialog.size = Vector2(1400, 800) + import_dialog.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS + import_dialog.content_scale_factor = 3 + import_dialog.file_mode = FileDialog.FILE_MODE_OPEN_DIR + import_dialog.access = FileDialog.ACCESS_FILESYSTEM + import_dialog.dir_selected.connect(_on_import_folder_selected) + add_child(import_dialog) + import_dialog.popup_centered() + +func _on_import_folder_selected(folder_path: String): + var config_file_path = folder_path + "/audio_config.dat" + if not FileAccess.file_exists(config_file_path): + push_error("所选文件夹中没有找到 audio_config.dat 配置文件") + return + # 确保目标目录存在 + var target_dir = "user://audio/" + current_scene_name + "/" + DirAccess.open("user://").make_dir_recursive("audio/" + current_scene_name) + # 复制配置文件 + copy_file(config_file_path, target_dir + "audio_config.dat") + # 复制所有音频文件 + var dir = DirAccess.open(folder_path) + if dir: + dir.list_dir_begin() + var file_name = dir.get_next() + while file_name != "": + if not dir.current_is_dir(): + var extension = file_name.get_extension().to_lower() + if extension in ["wav", "ogg", "mp3"]: + var source_path = folder_path + "/" + file_name + var target_path = target_dir + file_name + copy_file(source_path, target_path) + + file_name = dir.get_next() + dir.list_dir_end() + # 重新加载配置 + load_config() + refresh_sfx_list(SceneManager.get_ground()) + print("配置和音频文件已导入") + +func copy_file(source_path: String, target_path: String) -> bool: + var source_file = FileAccess.open(source_path, FileAccess.READ) + if not source_file: + push_error("无法读取文件: " + source_path) + return false + var target_file = FileAccess.open(target_path, FileAccess.WRITE) + if not target_file: + push_error("无法创建文件: " + target_path) + source_file.close() + return false + target_file.store_buffer(source_file.get_buffer(source_file.get_length())) + source_file.close() + target_file.close() + return true + +func _on_export_pressed(): + var desktop_path = OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP) + var export_folder = desktop_path + "/" + current_scene_name + "_audio_export" + var config_path = "user://audio/" + current_scene_name + "/audio_config.dat" + + # 创建导出文件夹 + var dir = DirAccess.open(desktop_path) + if not dir: + push_error("无法访问桌面目录") + return + + # 如果文件夹已存在,先删除 + if dir.dir_exists(export_folder): + remove_directory_recursive(export_folder) + + dir.make_dir(current_scene_name + "_audio_export") + + var exported_files = [] + var failed_files = [] + + # 1. 导出配置文件 + if FileAccess.file_exists(config_path): + var source_file = FileAccess.open(config_path, FileAccess.READ) + var target_file = FileAccess.open(export_folder + "/audio_config.dat", FileAccess.WRITE) + + if source_file and target_file: + target_file.store_buffer(source_file.get_buffer(source_file.get_length())) + source_file.close() + target_file.close() + exported_files.append("audio_config.dat") + else: + failed_files.append("audio_config.dat") + push_error("配置文件导出失败") + else: + push_error("没有找到配置文件") + return + + # 2. 导出所有关联的音频文件 + var audio_dir = "user://audio/" + current_scene_name + "/" + + # 从配置数据中收集所有音频文件路径 + var audio_files_to_export = [] + + # 收集配置文件中引用的音频文件 + for node_name in config_data.keys(): + var node_config = config_data[node_name] + if node_config.has("stream"): + var stream_path = node_config["stream"] + if stream_path.begins_with("user://audio/" + current_scene_name + "/"): + audio_files_to_export.append(stream_path) + + # 收集当前目录下的所有音频文件 + var audio_dir_access = DirAccess.open(audio_dir) + if audio_dir_access: + audio_dir_access.list_dir_begin() + var file_name = audio_dir_access.get_next() + + while file_name != "": + if not audio_dir_access.current_is_dir(): + var full_path = audio_dir + file_name + var extension = file_name.get_extension().to_lower() + + # 检查是否是音频文件 + if extension in ["wav", "ogg", "mp3"]: + if not full_path in audio_files_to_export: + audio_files_to_export.append(full_path) + + file_name = audio_dir_access.get_next() + audio_dir_access.list_dir_end() + + # 导出音频文件 + for audio_path in audio_files_to_export: + if FileAccess.file_exists(audio_path): + var file_name = audio_path.get_file() + var source_file = FileAccess.open(audio_path, FileAccess.READ) + var target_file = FileAccess.open(export_folder + "/" + file_name, FileAccess.WRITE) + + if source_file and target_file: + target_file.store_buffer(source_file.get_buffer(source_file.get_length())) + source_file.close() + target_file.close() + exported_files.append(file_name) + else: + failed_files.append(file_name) + if source_file: + source_file.close() + if target_file: + target_file.close() + else: + failed_files.append(audio_path.get_file() + " (文件不存在)") + + # 3. 创建导出说明文件 + create_export_readme(export_folder, exported_files, failed_files) + + # 显示导出结果 + var message = "导出完成!\n导出位置: " + export_folder + "\n" + message += "成功导出 " + str(exported_files.size()) + " 个文件" + + if failed_files.size() > 0: + message += "\n失败 " + str(failed_files.size()) + " 个文件: " + str(failed_files) + + print(message) + + # 可选:打开导出文件夹 + OS.shell_open(export_folder) + +func create_export_readme(export_folder: String, exported_files: Array, failed_files: Array): + var readme_path = export_folder + "/README.txt" + var readme_file = FileAccess.open(readme_path, FileAccess.WRITE) + + if readme_file: + var content = "音效配置导出说明\n" + content += "===================\n\n" + content += "场景名称: " + current_scene_name + "\n" + content += "导出时间: " + Time.get_datetime_string_from_system() + "\n\n" + + content += "导出文件清单:\n" + content += "-----------------\n" + for file_name in exported_files: + content += "✓ " + file_name + "\n" + + if failed_files.size() > 0: + content += "\n失败文件:\n" + content += "-----------------\n" + for file_name in failed_files: + content += "✗ " + file_name + "\n" + + content += "\n使用说明:\n" + content += "-----------------\n" + content += "1. audio_config.dat 是配置文件,包含音量和文件关联信息\n" + content += "2. 其他 .wav/.ogg/.mp3 文件是对应的音频资源\n" + content += "3. 导入时请将所有文件放在同一目录下\n" + + readme_file.store_string(content) + readme_file.close() + +func remove_directory_recursive(path: String): + var dir = DirAccess.open(path) + if dir: + dir.list_dir_begin() + var file_name = dir.get_next() + + while file_name != "": + var full_path = path + "/" + file_name + + if dir.current_is_dir(): + remove_directory_recursive(full_path) + else: + dir.remove(file_name) + + file_name = dir.get_next() + + dir.list_dir_end() + dir.remove(path) diff --git a/manager/archive_manager/sfx_config_panel.gd.uid b/manager/archive_manager/sfx_config_panel.gd.uid new file mode 100644 index 00000000..a79b6914 --- /dev/null +++ b/manager/archive_manager/sfx_config_panel.gd.uid @@ -0,0 +1 @@ +uid://dtwvx0vs0uoun diff --git a/manager/archive_manager/sfx_config_panel.tscn b/manager/archive_manager/sfx_config_panel.tscn new file mode 100644 index 00000000..65da7207 --- /dev/null +++ b/manager/archive_manager/sfx_config_panel.tscn @@ -0,0 +1,62 @@ +[gd_scene load_steps=2 format=3 uid="uid://b6ogrp5ec5nr3"] + +[ext_resource type="Script" uid="uid://dtwvx0vs0uoun" path="res://manager/archive_manager/sfx_config_panel.gd" id="1_386ty"] + +[node name="SfxConfigPanel" type="PanelContainer"] +custom_minimum_size = Vector2(500, 0) +offset_right = 508.0 +offset_bottom = 335.0 +mouse_filter = 1 +script = ExtResource("1_386ty") + +[node name="MainVBox" type="VBoxContainer" parent="."] +layout_mode = 2 + +[node name="HeaderHBox" type="HBoxContainer" parent="MainVBox"] +layout_mode = 2 + +[node name="Label" type="Label" parent="MainVBox/HeaderHBox"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_font_sizes/font_size = 18 +text = "音效配置面板" +horizontal_alignment = 1 + +[node name="ImportButton" type="Button" parent="MainVBox/HeaderHBox"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 8 +text = "导入配置" + +[node name="ExportButton" type="Button" parent="MainVBox/HeaderHBox"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 8 +text = "导出配置" + +[node name="ScrollContainer" type="ScrollContainer" parent="MainVBox"] +unique_name_in_owner = true +custom_minimum_size = Vector2(500, 400) +layout_mode = 2 +size_flags_vertical = 0 +horizontal_scroll_mode = 0 +vertical_scroll_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="MainVBox/ScrollContainer"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] +unique_name_in_owner = true + +[node name="FileDialog" type="FileDialog" parent="."] +unique_name_in_owner = true +title = "Open a File" +initial_position = 1 +size = Vector2i(1500, 1000) +content_scale_mode = 1 +content_scale_factor = 3.0 +ok_button_text = "Open" +file_mode = 0 +access = 2 +filters = PackedStringArray("*.wav", "*.ogg", "*.mp3") diff --git a/manager/scene/scene_manager.gd b/manager/scene/scene_manager.gd index 751800de..0d97f0d3 100644 --- a/manager/scene/scene_manager.gd +++ b/manager/scene/scene_manager.gd @@ -364,7 +364,7 @@ func enter_main_scene() -> void: get_tree().paused = false -#### Savings +#### debugging var savings_scene = preload("uid://d4jeeteyq8kk3") @@ -411,7 +411,7 @@ func show_settings() -> void: #### 游戏场景树暂停计数器,设置、memory、bag 等菜单都会导致 pause -## 目前有(6类): settings, panel, bag, note, memory, savings +## 目前有(6类): settings, panel, bag, note, memory, debugging var pause_counter_arr: Array[String] = [] var pause_counter_mutex := Mutex.new() diff --git a/project.godot b/project.godot index 40c9c88a..974efcbe 100644 --- a/project.godot +++ b/project.godot @@ -211,7 +211,7 @@ panel={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":80,"key_label":0,"unicode":112,"location":0,"echo":false,"script":null) ] } -savings={ +debugging={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":96,"key_label":0,"unicode":96,"location":0,"echo":false,"script":null) ] diff --git a/scene/ground/ground_loader.gd b/scene/ground/ground_loader.gd index a00dd3ed..1e61c2f2 100644 --- a/scene/ground/ground_loader.gd +++ b/scene/ground/ground_loader.gd @@ -231,7 +231,14 @@ func _add_ground() -> void: # 在 add child 之前,调整 ground 内部元素属性,在 on ground ready 前设置完成 if not Engine.is_editor_hint(): _setup_player_position() + + # debug 模式在 ground add 之前加载音频 + if GlobalConfig.DEBUG: + # headless 模式 + SfxConfigPanel.new().refresh_sfx_list(ground, true) + add_child(ground) + print( "GroundLoader add_ground finished:", ground.scene_name, diff --git a/scene/main.gd b/scene/main.gd index 45767ca6..be311fd6 100644 --- a/scene/main.gd +++ b/scene/main.gd @@ -37,7 +37,7 @@ func _unhandled_input(event: InputEvent) -> void: elif event.is_action_pressed("panel"): get_viewport().set_input_as_handled() SceneManager.show_panel() - elif event.is_action_pressed("savings"): + elif event.is_action_pressed("debugging"): if GlobalConfig.DEBUG: get_viewport().set_input_as_handled() SceneManager.show_savings() diff --git a/util/audio_loader.gd b/util/audio_loader.gd new file mode 100644 index 00000000..9ac382f9 --- /dev/null +++ b/util/audio_loader.gd @@ -0,0 +1,258 @@ +#GDScriptAudioImport v0.1 + +#MIT License +# +#Copyright (c) 2020 Gianclgar (Giannino Clemente) gianclgar@gmail.com +# +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: +# +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. +# +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +#SOFTWARE. + +#I honestly don't care that much, Kopimi ftw, but it's my little baby and I want it to look nice :3 + +class_name AudioLoader + +func report_errors(err, filepath): + # See: https://docs.godotengine.org/en/latest/classes/class_@globalscope.html#enum-globalscope-error + var result_hash = { + ERR_FILE_NOT_FOUND: "File: not found", + ERR_FILE_BAD_DRIVE: "File: Bad drive error", + ERR_FILE_BAD_PATH: "File: Bad path error.", + ERR_FILE_NO_PERMISSION: "File: No permission error.", + ERR_FILE_ALREADY_IN_USE: "File: Already in use error.", + ERR_FILE_CANT_OPEN: "File: Can't open error.", + ERR_FILE_CANT_WRITE: "File: Can't write error.", + ERR_FILE_CANT_READ: "File: Can't read error.", + ERR_FILE_UNRECOGNIZED: "File: Unrecognized error.", + ERR_FILE_CORRUPT: "File: Corrupt error.", + ERR_FILE_MISSING_DEPENDENCIES: "File: Missing dependencies error.", + ERR_FILE_EOF: "File: End of file (EOF) error." + } + if err in result_hash: + print("Error: ", result_hash[err], " ", filepath) + else: + print("Unknown error with file ", filepath, " error code: ", err) + +func loadfile(filepath): + var file_access = FileAccess.open(filepath, FileAccess.READ) + if file_access.get_error() != OK: + report_errors(file_access.get_error(), filepath) + file_access.close() + return AudioSample.new() + + var bytes = FileAccess.get_file_as_bytes(filepath) + # if File is wav + if filepath.ends_with(".wav"): + var newstream = AudioStreamWAV.load_from_buffer(bytes) + newstream.take_over_path(filepath) + + # #--------------------------- + # #parrrrseeeeee!!! :D + + # var bits_per_sample = 0 + # var i = 0 + # while true: + # if i >= len(bytes) - 4: # Failsafe, if there is no data bytes + # print("Data byte not found") + # break + + # var those4bytes = str(char(bytes[i])+char(bytes[i+1])+char(bytes[i+2])+char(bytes[i+3])) + + # if those4bytes == "RIFF": + # print ("RIFF OK at bytes " + str(i) + "-" + str(i+3)) + # #RIP bytes 4-7 integer for now + # if those4bytes == "WAVE": + # print ("WAVE OK at bytes " + str(i) + "-" + str(i+3)) + + # if those4bytes == "fmt ": + # print ("fmt OK at bytes " + str(i) + "-" + str(i+3)) + + # #get format subchunk size, 4 bytes next to "fmt " are an int32 + # var formatsubchunksize = bytes[i+4] + (bytes[i+5] << 8) + (bytes[i+6] << 16) + (bytes[i+7] << 24) + # print ("Format subchunk size: " + str(formatsubchunksize)) + + # #using formatsubchunk index so it's easier to understand what's going on + # var fsc0 = i+8 #fsc0 is byte 8 after start of "fmt " + + # #get format code [Bytes 0-1] + # var format_code = bytes[fsc0] + (bytes[fsc0+1] << 8) + # var format_name + # if format_code == 0: format_name = "8_BITS" + # elif format_code == 1: format_name = "16_BITS" + # elif format_code == 2: format_name = "IMA_ADPCM" + # else: + # format_name = "UNKNOWN (trying to interpret as 16_BITS)" + # format_code = 1 + # print ("Format: " + str(format_code) + " " + format_name) + # #assign format to our AudioSample + # newstream.format = format_code + + # #get channel num [Bytes 2-3] + # var channel_num = bytes[fsc0+2] + (bytes[fsc0+3] << 8) + # print ("Number of channels: " + str(channel_num)) + # #set our AudioSample to stereo if needed + # if channel_num == 2: newstream.stereo = true + + # #get sample rate [Bytes 4-7] + # var sample_rate = bytes[fsc0+4] + (bytes[fsc0+5] << 8) + (bytes[fsc0+6] << 16) + (bytes[fsc0+7] << 24) + # print ("Sample rate: " + str(sample_rate)) + # #set our AudioSample mixrate + # newstream.mix_rate = sample_rate + + # #get byte_rate [Bytes 8-11] because we can + # var byte_rate = bytes[fsc0+8] + (bytes[fsc0+9] << 8) + (bytes[fsc0+10] << 16) + (bytes[fsc0+11] << 24) + # print ("Byte rate: " + str(byte_rate)) + + # #same with bits*sample*channel [Bytes 12-13] + # var bits_sample_channel = bytes[fsc0+12] + (bytes[fsc0+13] << 8) + # print ("BitsPerSample * Channel / 8: " + str(bits_sample_channel)) + + # #aaaand bits per sample/bitrate [Bytes 14-15] + # bits_per_sample = bytes[fsc0+14] + (bytes[fsc0+15] << 8) + # print ("Bits per sample: " + str(bits_per_sample)) + + # if those4bytes == "data": + # assert(bits_per_sample != 0) + + # var audio_data_size = bytes[i+4] + (bytes[i+5] << 8) + (bytes[i+6] << 16) + (bytes[i+7] << 24) + # print ("Audio data/stream size is " + str(audio_data_size) + " bytes") + + # var data_entry_point = (i+8) + # print ("Audio data starts at byte " + str(data_entry_point)) + + # var data = bytes.subarray(data_entry_point, data_entry_point+audio_data_size-1) + + # if bits_per_sample in [24, 32]: + # newstream.data = convert_to_16bit(data, bits_per_sample) + # else: + # newstream.data = data + + # break # the data will be at the end, end searching here + + # i += 1 + # # end of parsing + # #--------------------------- + + # #get samples and set loop end + # var samplenum = newstream.data.size() / 4 + # newstream.loop_end = samplenum + # newstream.loop_mode = 1 #change to 0 or delete this line if you don't want loop, also check out modes 2 and 3 in the docs + return newstream #:D + + #if file is ogg + elif filepath.ends_with(".ogg"): + var newstream = AudioStreamOggVorbis.load_from_buffer(bytes) + newstream.take_over_path(filepath) + # newstream.loop = true #set to false or delete this line if you don't want to loop + return newstream + + #if file is mp3 + elif filepath.ends_with(".mp3"): + var newstream = AudioStreamMP3.load_from_buffer(bytes) + newstream.take_over_path(filepath) + # newstream.loop = true #set to false or delete this line if you don't want to loop + return newstream + + else: + print ("ERROR: Wrong filetype or format") + +# Converts .wav data from 24 or 32 bits to 16 +# +# These conversions are SLOW in GDScript +# on my one test song, 32 -> 16 was around 3x slower than 24 -> 16 +# +# I couldn't get threads to help very much +# They made the 24bit case about 2x faster in my test file +# And the 32bit case abour 50% slower +# I don't wanna risk it always being slower on other files +# And really, the solution would be to handle it in a low-level language +func convert_to_16bit(data: PackedByteArray, from: int) -> PackedByteArray: + print("converting to 16-bit from %d" % from) + var time = Time.get_ticks_msec() + # 24 bit .wav's are typically stored as integers + # so we just grab the 2 most significant bytes and ignore the other + if from == 24: + var j = 0 + for i in range(0, data.size(), 3): + data[j] = data[i+1] + data[j+1] = data[i+2] + j += 2 + data.resize(data.size() * 2 / 3) + # 32 bit .wav's are typically stored as floating point numbers + # so we need to grab all 4 bytes and interpret them as a float first + if from == 32: + var spb := StreamPeerBuffer.new() + var single_float: float + var value: int + for i in range(0, data.size(), 4): + # spb.data_array = data.subarray(i, i+3) + spb.data_array = data.slice(i, i+4) + single_float = spb.get_float() + value = single_float * 32768 + data[i/2] = value + data[i/2+1] = value >> 8 + data.resize(data.size() / 2) + print("Took %f seconds for slow conversion" % ((Time.get_ticks_msec() - time) / 1000.0)) + return data + + +# ---------- REFERENCE --------------- +# note: typical values doesn't always match + +#Positions Typical Value Description +# +#1 - 4 "RIFF" Marks the file as a RIFF multimedia file. +# Characters are each 1 byte long. +# +#5 - 8 (integer) The overall file size in bytes (32-bit integer) +# minus 8 bytes. Typically, you'd fill this in after +# file creation is complete. +# +#9 - 12 "WAVE" RIFF file format header. For our purposes, it +# always equals "WAVE". +# +#13-16 "fmt " Format sub-chunk marker. Includes trailing null. +# +#17-20 16 Length of the rest of the format sub-chunk below. +# +#21-22 1 Audio format code, a 2 byte (16 bit) integer. +# 1 = PCM (pulse code modulation). +# +#23-24 2 Number of channels as a 2 byte (16 bit) integer. +# 1 = mono, 2 = stereo, etc. +# +#25-28 44100 Sample rate as a 4 byte (32 bit) integer. Common +# values are 44100 (CD), 48000 (DAT). Sample rate = +# number of samples per second, or Hertz. +# +#29-32 176400 (SampleRate * BitsPerSample * Channels) / 8 +# This is the Byte rate. +# +#33-34 4 (BitsPerSample * Channels) / 8 +# 1 = 8 bit mono, 2 = 8 bit stereo or 16 bit mono, 4 +# = 16 bit stereo. +# +#35-36 16 Bits per sample. +# +#37-40 "data" Data sub-chunk header. Marks the beginning of the +# raw data section. +# +#41-44 (integer) The number of bytes of the data section below this +# point. Also equal to (#ofSamples * #ofChannels * +# BitsPerSample) / 8 +# +#45+ The raw audio data. diff --git a/util/audio_loader.gd.uid b/util/audio_loader.gd.uid new file mode 100644 index 00000000..43b1017c --- /dev/null +++ b/util/audio_loader.gd.uid @@ -0,0 +1 @@ +uid://dho44deftogm8 From aaa7dc26bbf763f6124aabf01b1038e3c48bccf7 Mon Sep 17 00:00:00 2001 From: cakipaul Date: Sat, 19 Jul 2025 15:02:32 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=20sfx=5Fconfig=5Fpanel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manager/archive_manager/debug_panel.gd | 2 - manager/archive_manager/savings_panel.gd | 2 +- manager/archive_manager/sfx_config_panel.gd | 73 +++++++++++++----- manager/archive_manager/sfx_config_panel.tscn | 6 ++ .../audio_manager/vibe_group_collection.tres | 24 +----- manager/scene/scene_manager.gd | 10 ++- scene/entity/audio/sfx.gd | 55 +++++++++++--- scene/ground/ground_loader.gd | 5 +- scene/ground/scene/c02/s01_公寓门口.tscn | 34 ++++++--- scene/ground/scene/c02/s03_院子.tscn | 26 ++++--- scene/ground/scene/c03/s01_三楼.tscn | 2 +- util/audio_loader.gd | 76 +++++++++---------- 12 files changed, 194 insertions(+), 121 deletions(-) diff --git a/manager/archive_manager/debug_panel.gd b/manager/archive_manager/debug_panel.gd index a0bf282a..681a70b1 100644 --- a/manager/archive_manager/debug_panel.gd +++ b/manager/archive_manager/debug_panel.gd @@ -4,7 +4,6 @@ extends CanvasLayer func _ready() -> void: - AudioManager.process_mode = Node.PROCESS_MODE_PAUSABLE SceneManager.toggle_pause_counter(true, "debugging") layer = GlobalConfig.CANVAS_LAYER_SETTINGS quit_debug_button.pressed.connect(_on_quit_debug_button_pressed) @@ -31,7 +30,6 @@ func _on_quit_debug_button_pressed() -> void: func _exit_tree() -> void: - AudioManager.process_mode = Node.PROCESS_MODE_ALWAYS SceneManager.toggle_pause_counter(false, "debugging") diff --git a/manager/archive_manager/savings_panel.gd b/manager/archive_manager/savings_panel.gd index 6ab93c7d..3955f175 100644 --- a/manager/archive_manager/savings_panel.gd +++ b/manager/archive_manager/savings_panel.gd @@ -236,7 +236,7 @@ func _load_manual_archive(_id: int, data: Dictionary) -> void: ArchiveManager.archive = saving_archive print("Loading archive from: ", data.path, " to: ", target_path) # Reload current scene - get_tree().reload_current_scene() + SceneManager.enter_main_scene() else: _show_notification("加载存档失败:" + data.name) diff --git a/manager/archive_manager/sfx_config_panel.gd b/manager/archive_manager/sfx_config_panel.gd index 4b5a7a1d..8f8cb83e 100644 --- a/manager/archive_manager/sfx_config_panel.gd +++ b/manager/archive_manager/sfx_config_panel.gd @@ -6,6 +6,7 @@ extends Control # 面板相关 @onready var scroll_container: ScrollContainer = %ScrollContainer @onready var vbox_container: VBoxContainer = %VBoxContainer +@onready var reset_button: Button = %ResetButton @onready var import_button: Button = %ImportButton @onready var export_button: Button = %ExportButton # 音频预览播放器 @@ -21,6 +22,7 @@ var current_scene_name: String = "" func _ready(): file_dialog.file_selected.connect(_on_file_selected) + reset_button.pressed.connect(_on_reset_pressed) import_button.pressed.connect(_on_import_pressed) export_button.pressed.connect(_on_export_pressed) # 初始加载 @@ -29,14 +31,12 @@ func _ready(): # 1. 检测 current_scene 下 Sfx 节点 func refresh_sfx_list(ground: Ground2D, headless := false): - if not headless: - clear_ui() sfx_nodes.clear() current_scene_name = GroundLoader.get_ground_scene_readable_name(ground.scene_name) find_sfx_nodes(ground) load_config() if not headless: - create_ui_items() + refresh_ui() var ignore_class_list = ["Portal2D", "Interactable2D", "Note2D", "Inspectable2D", "Pickable2D", "Npc2D", "Ambush2D"] @@ -62,6 +62,11 @@ func create_ui_items(): for sfx_node in sfx_nodes: create_sfx_item(sfx_node) +func refresh_ui(): + clear_ui() + create_ui_items() + + func create_sfx_item(sfx_node: Node): var item_container = VBoxContainer.new() item_container.add_theme_constant_override("separation", 8) @@ -120,24 +125,29 @@ func create_sfx_item(sfx_node: Node): stream_vbox.add_child(stream_hbox) var stream_name_label = Label.new() - if sfx_node.stream: - stream_name_label.text = sfx_node.stream.resource_path.get_file() - else: - stream_name_label.text = "无音频文件" stream_name_label.custom_minimum_size.x = 150 + _set_stream_name_label(sfx_node, stream_name_label) stream_hbox.add_child(stream_name_label) # 预览播放按钮 var preview_button = Button.new() preview_button.text = "▶" preview_button.custom_minimum_size = Vector2(30, 30) - preview_button.pressed.connect(func(): preview_audio(sfx_node)) + preview_button.pressed.connect(preview_audio.bind(sfx_node)) stream_hbox.add_child(preview_button) + + # 恢复默认按钮 + if sfx_node.stream_was_replaced(): + var reset_button = Button.new() + reset_button.text = "🗑️" + reset_button.custom_minimum_size = Vector2(30, 30) + reset_button.pressed.connect(reset_audio.bind(sfx_node)) + stream_hbox.add_child(reset_button) # 3. 上传文件按钮 var upload_button = Button.new() upload_button.text = "上传音频" - upload_button.pressed.connect(func(): open_file_dialog(sfx_node, stream_name_label)) + upload_button.pressed.connect(open_file_dialog.bind(sfx_node, stream_name_label)) stream_hbox.add_child(upload_button) # 分割线 @@ -148,12 +158,28 @@ func create_sfx_item(sfx_node: Node): item_container.set_meta("sfx_node", sfx_node) item_container.set_meta("stream_label", stream_name_label) -func preview_audio(sfx_node: Node): + +func _set_stream_name_label(sfx_node:Sfx, stream_name_label:Label) -> void: + if sfx_node.stream: + stream_name_label.text = sfx_node.stream.resource_path.get_file() + else: + stream_name_label.text = "无音频文件" + + +func preview_audio(sfx_node: Sfx): if sfx_node.stream: preview_player.stream = sfx_node.stream preview_player.volume_db = sfx_node.volume_db preview_player.play() + +func reset_audio(sfx_node: Sfx): + sfx_node.reset_original_stream() + config_data.erase(sfx_node.name) + save_config() + refresh_ui() + + var current_upload_node: Node var current_stream_label: Label @@ -162,46 +188,44 @@ func open_file_dialog(sfx_node: Node, stream_label: Label): current_stream_label = stream_label file_dialog.popup_centered() + func _on_file_selected(path: String): if not current_upload_node: return - copy_and_load_audio_file(path, current_upload_node, current_stream_label) + # 3. 复制文件并加载 func copy_and_load_audio_file(source_path: String, sfx_node: Node, stream_label: Label): var file_name = source_path.get_file() var audio_dir = "user://audio/" + current_scene_name + "/" var target_path = audio_dir + file_name - # 确保目录存在 DirAccess.open("user://").make_dir_recursive("audio/" + current_scene_name) - # 复制文件 var source_file = FileAccess.open(source_path, FileAccess.READ) if not source_file: push_error("无法读取源文件: " + source_path) return - var target_file = FileAccess.open(target_path, FileAccess.WRITE) if not target_file: push_error("无法创建目标文件: " + target_path) source_file.close() return - target_file.store_buffer(source_file.get_buffer(source_file.get_length())) source_file.close() target_file.close() - # 加载新的音频流 var new_stream = AudioLoader.new().loadfile(target_path) if new_stream: - sfx_node.stream = new_stream + sfx_node.replace_stream(new_stream) stream_label.text = file_name save_node_config(sfx_node.name, "stream", target_path) print("音频文件已更新: ", sfx_node.name, " -> ", file_name) else: push_error("无法加载音频文件: " + target_path) + refresh_ui() + # 4. 配置保存与加载 func save_node_config(node_name: String, property: String, value): @@ -233,6 +257,7 @@ func load_config(): else: config_data = {} + func apply_config(): for sfx_node in sfx_nodes: if config_data.has(sfx_node.name): @@ -245,7 +270,17 @@ func apply_config(): var new_stream = AudioLoader.new().loadfile(stream_path) # var new_stream = load(stream_path) if new_stream: - sfx_node.stream = new_stream + sfx_node.replace_stream(new_stream) + + +func _on_reset_pressed() -> void: + for sfx_node in sfx_nodes: + sfx_node.reset_original_stream() + var config_file_path = "user://audio/" + current_scene_name + "/" + "/audio_config.dat" + if FileAccess.file_exists(config_file_path): + DirAccess.remove_absolute(config_file_path) + SceneManager.enter_main_scene() + # 5. Import/Export 功能 func _on_import_pressed(): @@ -282,11 +317,9 @@ func _on_import_folder_selected(folder_path: String): var source_path = folder_path + "/" + file_name var target_path = target_dir + file_name copy_file(source_path, target_path) - file_name = dir.get_next() dir.list_dir_end() # 重新加载配置 - load_config() refresh_sfx_list(SceneManager.get_ground()) print("配置和音频文件已导入") diff --git a/manager/archive_manager/sfx_config_panel.tscn b/manager/archive_manager/sfx_config_panel.tscn index 65da7207..2f014ea6 100644 --- a/manager/archive_manager/sfx_config_panel.tscn +++ b/manager/archive_manager/sfx_config_panel.tscn @@ -22,6 +22,12 @@ theme_override_font_sizes/font_size = 18 text = "音效配置面板" horizontal_alignment = 1 +[node name="ResetButton" type="Button" parent="MainVBox/HeaderHBox"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 8 +text = "重置所有配置" + [node name="ImportButton" type="Button" parent="MainVBox/HeaderHBox"] unique_name_in_owner = true layout_mode = 2 diff --git a/manager/audio_manager/vibe_group_collection.tres b/manager/audio_manager/vibe_group_collection.tres index 9048fe43..7f8c1981 100644 --- a/manager/audio_manager/vibe_group_collection.tres +++ b/manager/audio_manager/vibe_group_collection.tres @@ -1,4 +1,4 @@ -[gd_resource type="Resource" script_class="VibeGroupCollection" load_steps=22 format=3 uid="uid://bfhwn1v0c2io7"] +[gd_resource type="Resource" script_class="VibeGroupCollection" load_steps=18 format=3 uid="uid://bfhwn1v0c2io7"] [ext_resource type="Script" uid="uid://cy1ngx5no67v" path="res://manager/audio_manager/vibe_group.gd" id="1_0bbao"] [ext_resource type="Script" uid="uid://bo8gxwe8hfs01" path="res://manager/audio_manager/vibe_group_collection.gd" id="2_h4hph"] @@ -10,8 +10,6 @@ [ext_resource type="AudioStream" uid="uid://6oc0cgc3mbqb" path="res://asset/audio/sfx/环境音/白噪音/白噪声楼道2.ogg" id="7_lca37"] [ext_resource type="AudioStream" uid="uid://c6ehv3lgway26" path="res://asset/audio/sfx/环境音/白噪音/白噪声诡异室外.ogg" id="8_646q0"] [ext_resource type="AudioStream" uid="uid://s7uigovfp5g3" path="res://asset/audio/sfx/环境音/第一章/火灾演出.ogg" id="9_wuwx1"] -[ext_resource type="AudioStream" uid="uid://d0ef0felylt8d" path="res://asset/audio/sfx/环境音/第一章/氛围不受欢迎的存在.ogg" id="10_uwtc1"] -[ext_resource type="AudioStream" uid="uid://bal423qlb3jp2" path="res://asset/audio/sfx/环境音/点缀音/sfx_夜晚虫鸣.ogg" id="11_scrw7"] [sub_resource type="Resource" id="Resource_bjndi"] script = ExtResource("1_0bbao") @@ -76,25 +74,7 @@ base_sound_db = 0.0 embellishments = Array[ExtResource("3_scrw7")]([]) metadata/_custom_type_script = "uid://cy1ngx5no67v" -[sub_resource type="Resource" id="Resource_f75a1"] -script = ExtResource("1_0bbao") -group_name = &"氛围_不受欢迎的存在" -group_db = 0.0 -base_sound = ExtResource("10_uwtc1") -base_sound_db = -12.0 -embellishments = Array[ExtResource("3_scrw7")]([]) -metadata/_custom_type_script = "uid://cy1ngx5no67v" - -[sub_resource type="Resource" id="Resource_scrw7"] -script = ExtResource("1_0bbao") -group_name = &"夜晚虫鸣" -group_db = 0.0 -base_sound = ExtResource("11_scrw7") -base_sound_db = -10.0 -embellishments = Array[ExtResource("3_scrw7")]([]) -metadata/_custom_type_script = "uid://cy1ngx5no67v" - [resource] script = ExtResource("2_h4hph") -groups = Array[ExtResource("1_0bbao")]([SubResource("Resource_bjndi"), SubResource("Resource_chrc1"), SubResource("Resource_7c7wx"), SubResource("Resource_an5bn"), SubResource("Resource_egnaw"), SubResource("Resource_e3r3f"), SubResource("Resource_j0xlt"), SubResource("Resource_f75a1"), SubResource("Resource_scrw7")]) +groups = Array[ExtResource("1_0bbao")]([SubResource("Resource_bjndi"), SubResource("Resource_chrc1"), SubResource("Resource_7c7wx"), SubResource("Resource_an5bn"), SubResource("Resource_egnaw"), SubResource("Resource_e3r3f"), SubResource("Resource_j0xlt")]) metadata/_custom_type_script = "uid://bo8gxwe8hfs01" diff --git a/manager/scene/scene_manager.gd b/manager/scene/scene_manager.gd index 0d97f0d3..175ea621 100644 --- a/manager/scene/scene_manager.gd +++ b/manager/scene/scene_manager.gd @@ -7,6 +7,8 @@ enum VIBE { TOUCHING, } +signal pause_counter_updated + # 从 ground loader 控制该信号 # 建议使用 CONNECT_ONE_SHOT 来连接 ground ready 与 start 等信号 @warning_ignore("unused_signal") @@ -354,14 +356,14 @@ var main_scene = preload("uid://dygvcmykn02n8") func enter_main_scene() -> void: - # 防止撕裂帧 - await get_tree().process_frame - get_tree().change_scene_to_packed.call_deferred(main_scene) # get_tree().change_scene_to_file.call_deferred("uid://dygvcmykn02n8") if pause_counter_arr.size() > 0: printerr("enter_main_scene: pause_counter_arr is not empty, resetting pause counter") pause_counter_arr.clear() get_tree().paused = false + # 防止撕裂帧 + await get_tree().process_frame + get_tree().change_scene_to_packed.call_deferred(main_scene) #### debugging @@ -426,6 +428,8 @@ func toggle_pause_counter(plus := true, from := "") -> void: print("SceneTree pause_counter_arr: ", pause_counter_arr) get_tree().paused = len(pause_counter_arr) > 0 pause_counter_mutex.unlock() + # 增删结束后再发射信号 + pause_counter_updated.emit() func quit_game() -> void: diff --git a/scene/entity/audio/sfx.gd b/scene/entity/audio/sfx.gd index 113d1e60..d901d5ae 100644 --- a/scene/entity/audio/sfx.gd +++ b/scene/entity/audio/sfx.gd @@ -1,8 +1,11 @@ @tool class_name Sfx extends AudioStreamPlayer +const META_ORIGINAL_STREAM = &"original_stream" + @export_enum("交互与效果音", "BGM", "场景背景音") var mode := "交互与效果音": set(value): + _set_up_process_mode_by_mode() mode = value notify_property_list_changed() @@ -13,19 +16,36 @@ 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 + # 记录原 stream + if stream: + set_meta(META_ORIGINAL_STREAM, stream) + else: + set_meta(META_ORIGINAL_STREAM, null) + _set_up_process_mode_by_mode() finished.connect(_on_finished) # ground 退出时,process mode 切换为 always,ease out SceneManager.ground_transition_pre_paused.connect(_on_ground_transition_pre_paused) + SceneManager.pause_counter_updated.connect(_on_pause_counter_updated) + + +func _on_pause_counter_updated() -> void: + _set_up_process_mode_by_mode() + + +func _set_up_process_mode_by_mode(): + # 如果是 debug panel,则 pause + if mode == "场景背景音" and not SceneManager.pause_counter_arr.has("debugging"): + process_mode = Node.PROCESS_MODE_ALWAYS + else: + process_mode = Node.PROCESS_MODE_PAUSABLE func _on_ground_transition_pre_paused(): @@ -40,6 +60,25 @@ func _on_finished() -> void: play() +func reset_original_stream(ignore_null := true): + var original_stream = get_meta(META_ORIGINAL_STREAM) + if original_stream != null: + replace_stream(original_stream) + elif not ignore_null: + stream = null + + +func replace_stream(new_stream: AudioStream) -> void: + stop() + stream = new_stream + if autoplay and is_node_ready(): + play() + + +func stream_was_replaced() -> bool: + return get_meta(META_ORIGINAL_STREAM) != stream + + func resart(ease_duration := 1.0): easing_kill(ease_duration).tween_callback(play) @@ -75,18 +114,17 @@ func _get_property_list() -> Array[Dictionary]: "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 == "感应玩家操作" + return property == "循环播放" or property == "感应玩家操作" func _property_get_revert(property: StringName) -> Variant: - if property == "自动开始" or property == "循环播放": + if property == "循环播放": return true elif property == "感应玩家操作": return false @@ -96,11 +134,6 @@ func _property_get_revert(property: StringName) -> Variant: 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 @@ -113,8 +146,6 @@ func _set(property: StringName, value: Variant) -> bool: func _get(property: StringName) -> Variant: if mode != "场景背景音": return null - if property == "自动开始": - return scene_autostart elif property == "循环播放": return scene_loop elif property == "感应玩家操作": diff --git a/scene/ground/ground_loader.gd b/scene/ground/ground_loader.gd index 1e61c2f2..eeff8266 100644 --- a/scene/ground/ground_loader.gd +++ b/scene/ground/ground_loader.gd @@ -232,12 +232,13 @@ func _add_ground() -> void: if not Engine.is_editor_hint(): _setup_player_position() - # debug 模式在 ground add 之前加载音频 + add_child(ground) + # debug 模式在 ground add 之后加载音频 + # 防止影响 Sfx 的 META 设置 ORIGINAL_STREAM if GlobalConfig.DEBUG: # headless 模式 SfxConfigPanel.new().refresh_sfx_list(ground, true) - add_child(ground) print( "GroundLoader add_ground finished:", diff --git a/scene/ground/scene/c02/s01_公寓门口.tscn b/scene/ground/scene/c02/s01_公寓门口.tscn index 455fcce5..c5d23a58 100644 --- a/scene/ground/scene/c02/s01_公寓门口.tscn +++ b/scene/ground/scene/c02/s01_公寓门口.tscn @@ -1,10 +1,12 @@ -[gd_scene load_steps=12 format=3 uid="uid://bbs7yy5aofw1v"] +[gd_scene load_steps=14 format=3 uid="uid://bbs7yy5aofw1v"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_c4tdi"] [ext_resource type="Script" uid="uid://jkselt4d5q4r" path="res://scene/ground/scene/c02/s01_公寓门口.gd" id="2_jfumy"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_bhi7l"] +[ext_resource type="AudioStream" uid="uid://dvc2emnfcmabx" path="res://asset/audio/sfx/环境音/白噪音/白噪声楼道1.ogg" id="4_ev3cr"] +[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="5_ev3cr"] [ext_resource type="Texture2D" uid="uid://d05pqud4yoxx3" path="res://asset/art/scene/c02/s01_公寓门口/bg_公寓门口.png" id="5_j2ctx"] [ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="6_bhi7l"] +[ext_resource type="AudioStream" uid="uid://bal423qlb3jp2" path="res://asset/audio/sfx/环境音/点缀音/sfx_夜晚虫鸣.ogg" id="6_ev3cr"] [ext_resource type="PackedScene" uid="uid://ci5anaxsa1apl" path="res://scene/entity/inspectable.tscn" id="7_vc2dw"] [ext_resource type="Texture2D" uid="uid://qls0yc054048" path="res://asset/art/scene/c02/小蝉寻人启事/e_寻人启事残破.png" id="8_j2ctx"] [ext_resource type="Texture2D" uid="uid://cuyfloebe2mht" path="res://asset/art/scene/c02/小蝉寻人启事/ux_寻人启事残破.png" id="9_bhi7l"] @@ -21,15 +23,27 @@ player_y = 60 [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_jfumy") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_bhi7l") -autoplay_group = &"c02_楼道1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +stream = ExtResource("4_ev3cr") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("5_ev3cr") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="VibeSfx虫鸣" type="Node" parent="Ground/AnimationPlayer" index="1"] -script = ExtResource("3_bhi7l") -autoplay_group = &"夜晚虫鸣" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景虫鸣" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] +stream = ExtResource("6_ev3cr") +volume_db = -10.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("5_ev3cr") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("5_j2ctx") diff --git a/scene/ground/scene/c02/s03_院子.tscn b/scene/ground/scene/c02/s03_院子.tscn index b6eabe5d..78fc4f94 100644 --- a/scene/ground/scene/c02/s03_院子.tscn +++ b/scene/ground/scene/c02/s03_院子.tscn @@ -2,6 +2,7 @@ [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_0dylx"] [ext_resource type="Script" uid="uid://dsp5plrdkrsd7" path="res://scene/ground/scene/c02/s03_院子.gd" id="2_dt5aj"] +[ext_resource type="AudioStream" uid="uid://d0ef0felylt8d" path="res://asset/audio/sfx/环境音/第一章/氛围不受欢迎的存在.ogg" id="3_2b6vx"] [ext_resource type="Texture2D" uid="uid://b3odt4ojsvu5n" path="res://asset/art/scene/c02/s03_公寓一楼院子/bg_一楼.png" id="3_sqv8l"] [ext_resource type="SpriteFrames" uid="uid://3nas025c2c5u" path="res://asset/art/gif/c02_杂项/c02_杂项_frames.tres" id="4_gd6xp"] [ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_ygnci"] @@ -10,7 +11,6 @@ [ext_resource type="Texture2D" uid="uid://f8yjp5ggr8qw" path="res://asset/art/scene/c02/s03_公寓一楼院子/算卦布.png" id="6_1tart"] [ext_resource type="Texture2D" uid="uid://0uh6qaalhqju" path="res://asset/art/scene/c02/s11_一楼火灾/总背景/bg_院子1楼火灾.png" id="6_d7h4s"] [ext_resource type="AudioStream" uid="uid://bhaws2ungqaf5" path="res://asset/audio/sfx/交互/角色/sfx_哼歌.ogg" id="6_jhod7"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="6_lq23y"] [ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="6_t48d1"] [ext_resource type="AudioStream" uid="uid://civuwccn6v6yk" path="res://asset/audio/sfx/交互/第一章/sfx_闷雷声.ogg" id="6_vddfx"] [ext_resource type="Texture2D" uid="uid://bxqetnlx0bpv4" path="res://asset/art/scene/c02/门_贴图/1012保卫科.png" id="6_ygnci"] @@ -285,37 +285,43 @@ libraries = { } script = ExtResource("2_dt5aj") -[node name="Sfx闷雷" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +stream = ExtResource("3_2b6vx") +volume_db = -12.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_ygnci") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" + +[node name="Sfx闷雷" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] stream = ExtResource("6_vddfx") bus = &"game_sfx" script = ExtResource("4_ygnci") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="Sfx打开铁门后" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] +[node name="Sfx打开铁门后" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"] stream = ExtResource("5_qt2qg") volume_db = -20.0 bus = &"game_sfx" script = ExtResource("4_ygnci") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="Sfx小鞋落地" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"] +[node name="Sfx小鞋落地" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="3"] stream = ExtResource("7_df1yo") bus = &"game_sfx" script = ExtResource("4_ygnci") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="Sfx小蝉哼歌" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="3"] +[node name="Sfx小蝉哼歌" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="4"] stream = ExtResource("6_jhod7") volume_db = 16.0 bus = &"game_sfx" script = ExtResource("4_ygnci") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="VibeSfx氛围" type="Node" parent="Ground/AnimationPlayer" index="4"] -script = ExtResource("6_lq23y") -autoplay_group = &"氛围_不受欢迎的存在" -metadata/_custom_type_script = "uid://cpejxlfni6n52" - [node name="Sfx牵手演出氛围音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="5"] stream = ExtResource("9_2b6vx") bus = &"game_sfx" diff --git a/scene/ground/scene/c03/s01_三楼.tscn b/scene/ground/scene/c03/s01_三楼.tscn index 5036d538..573e3186 100644 --- a/scene/ground/scene/c03/s01_三楼.tscn +++ b/scene/ground/scene/c03/s01_三楼.tscn @@ -200,7 +200,7 @@ position = Vector2(34, 8) [node name="portal_right" parent="Ground/DeployLayer" index="1"] position = Vector2(697, 18) target_scene = "c02_s06" -target_portal = "right" +target_portal = "3" [node name="互动公告" type="Sprite2D" parent="Ground/DeployLayer" index="2"] position = Vector2(377, 30) diff --git a/util/audio_loader.gd b/util/audio_loader.gd index 9ac382f9..70e1b915 100644 --- a/util/audio_loader.gd +++ b/util/audio_loader.gd @@ -170,44 +170,44 @@ func loadfile(filepath): else: print ("ERROR: Wrong filetype or format") -# Converts .wav data from 24 or 32 bits to 16 -# -# These conversions are SLOW in GDScript -# on my one test song, 32 -> 16 was around 3x slower than 24 -> 16 -# -# I couldn't get threads to help very much -# They made the 24bit case about 2x faster in my test file -# And the 32bit case abour 50% slower -# I don't wanna risk it always being slower on other files -# And really, the solution would be to handle it in a low-level language -func convert_to_16bit(data: PackedByteArray, from: int) -> PackedByteArray: - print("converting to 16-bit from %d" % from) - var time = Time.get_ticks_msec() - # 24 bit .wav's are typically stored as integers - # so we just grab the 2 most significant bytes and ignore the other - if from == 24: - var j = 0 - for i in range(0, data.size(), 3): - data[j] = data[i+1] - data[j+1] = data[i+2] - j += 2 - data.resize(data.size() * 2 / 3) - # 32 bit .wav's are typically stored as floating point numbers - # so we need to grab all 4 bytes and interpret them as a float first - if from == 32: - var spb := StreamPeerBuffer.new() - var single_float: float - var value: int - for i in range(0, data.size(), 4): - # spb.data_array = data.subarray(i, i+3) - spb.data_array = data.slice(i, i+4) - single_float = spb.get_float() - value = single_float * 32768 - data[i/2] = value - data[i/2+1] = value >> 8 - data.resize(data.size() / 2) - print("Took %f seconds for slow conversion" % ((Time.get_ticks_msec() - time) / 1000.0)) - return data +# # Converts .wav data from 24 or 32 bits to 16 +# # +# # These conversions are SLOW in GDScript +# # on my one test song, 32 -> 16 was around 3x slower than 24 -> 16 +# # +# # I couldn't get threads to help very much +# # They made the 24bit case about 2x faster in my test file +# # And the 32bit case abour 50% slower +# # I don't wanna risk it always being slower on other files +# # And really, the solution would be to handle it in a low-level language +# func convert_to_16bit(data: PackedByteArray, from: int) -> PackedByteArray: +# print("converting to 16-bit from %d" % from) +# var time = Time.get_ticks_msec() +# # 24 bit .wav's are typically stored as integers +# # so we just grab the 2 most significant bytes and ignore the other +# if from == 24: +# var j = 0 +# for i in range(0, data.size(), 3): +# data[j] = data[i+1] +# data[j+1] = data[i+2] +# j += 2 +# data.resize(data.size() * 2 / 3) +# # 32 bit .wav's are typically stored as floating point numbers +# # so we need to grab all 4 bytes and interpret them as a float first +# if from == 32: +# var spb := StreamPeerBuffer.new() +# var single_float: float +# var value: int +# for i in range(0, data.size(), 4): +# # spb.data_array = data.subarray(i, i+3) +# spb.data_array = data.slice(i, i+4) +# single_float = spb.get_float() +# value = single_float * 32768 +# data[i/2] = value +# data[i/2+1] = value >> 8 +# data.resize(data.size() / 2) +# print("Took %f seconds for slow conversion" % ((Time.get_ticks_msec() - time) / 1000.0)) +# return data # ---------- REFERENCE --------------- From 85475ff54942aa0261a184839f520b36a71f3c00 Mon Sep 17 00:00:00 2001 From: cakipaul Date: Sun, 20 Jul 2025 18:58:20 +0800 Subject: [PATCH 3/3] =?UTF-8?q?VibeSfx=20=E6=9B=BF=E6=8D=A2=E4=B8=BA=20Sfx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manager/archive_manager/debug_panel.gd | 2 + manager/archive_manager/sfx_config_panel.gd | 76 +++++++++++++------ scene/entity/audio/sfx.gd | 7 +- .../ground/scene/c01/s06_孤儿院长廊围墙.tscn | 1 + scene/ground/scene/c01/s07_书店外.tscn | 2 +- scene/ground/scene/c01/s08_书店.tscn | 4 +- scene/ground/scene/c01/s11_黄包车演出.tscn | 2 +- scene/ground/scene/c02/s01_公寓门口.tscn | 2 + scene/ground/scene/c02/s02_过道.tscn | 18 +++-- scene/ground/scene/c02/s03_院子.gd | 6 +- scene/ground/scene/c02/s03_院子.tscn | 26 +++++-- scene/ground/scene/c02/s04_保卫科.tscn | 20 +++-- scene/ground/scene/c02/s05_一楼内侧楼道.tscn | 17 +++-- scene/ground/scene/c02/s06_二楼.tscn | 17 +++-- scene/ground/scene/c02/s07_二楼内侧楼道.tscn | 20 +++-- scene/ground/scene/c02/s08_瞎子卧室.tscn | 17 +++-- scene/ground/scene/c02/s09_裂缝.tscn | 2 - scene/ground/scene/c02/s10_空房间.tscn | 17 +++-- scene/ground/scene/c02/s12_盒子猫.tscn | 17 +++-- scene/ground/scene/c02/s13_盒子猫二楼.tscn | 17 +++-- .../ground/scene/c02/s14_盒子猫二楼内侧.tscn | 20 +++-- .../ground/scene/c02/s15_盒子猫一楼内侧.tscn | 20 +++-- .../ground/scene/c02/s16_盒子猫三楼内侧.tscn | 20 +++-- scene/ground/scene/c02/s17_盒子猫三楼.tscn | 20 +++-- scene/ground/scene/c02/s18_盒子猫一楼.tscn | 20 +++-- scene/ground/scene/c03/s01_三楼.tscn | 20 +++-- 26 files changed, 288 insertions(+), 122 deletions(-) diff --git a/manager/archive_manager/debug_panel.gd b/manager/archive_manager/debug_panel.gd index 681a70b1..a0bf282a 100644 --- a/manager/archive_manager/debug_panel.gd +++ b/manager/archive_manager/debug_panel.gd @@ -4,6 +4,7 @@ extends CanvasLayer func _ready() -> void: + AudioManager.process_mode = Node.PROCESS_MODE_PAUSABLE SceneManager.toggle_pause_counter(true, "debugging") layer = GlobalConfig.CANVAS_LAYER_SETTINGS quit_debug_button.pressed.connect(_on_quit_debug_button_pressed) @@ -30,6 +31,7 @@ func _on_quit_debug_button_pressed() -> void: func _exit_tree() -> void: + AudioManager.process_mode = Node.PROCESS_MODE_ALWAYS SceneManager.toggle_pause_counter(false, "debugging") diff --git a/manager/archive_manager/sfx_config_panel.gd b/manager/archive_manager/sfx_config_panel.gd index 8f8cb83e..83edb200 100644 --- a/manager/archive_manager/sfx_config_panel.gd +++ b/manager/archive_manager/sfx_config_panel.gd @@ -67,6 +67,20 @@ func refresh_ui(): create_ui_items() +func _build_sfx_name(sfx: Sfx) -> String: + var parent_name = "" + var parent = sfx.get_parent() + while not parent_name and parent: + if parent and parent.get_script() and parent.get_script().get_global_name() in ignore_class_list: + parent_name = parent.name + else: + parent = parent.get_parent() + if parent_name: + return parent_name + " > " + sfx.name + else: + return sfx.name + + func create_sfx_item(sfx_node: Node): var item_container = VBoxContainer.new() item_container.add_theme_constant_override("separation", 8) @@ -74,7 +88,7 @@ func create_sfx_item(sfx_node: Node): # 节点名称标签 var name_label = Label.new() - name_label.text = sfx_node.name + name_label.text = _build_sfx_name(sfx_node) name_label.add_theme_font_size_override("font_size", 14) item_container.add_child(name_label) @@ -86,12 +100,22 @@ func create_sfx_item(sfx_node: Node): var volume_vbox = VBoxContainer.new() controls_hbox.add_child(volume_vbox) + + var volume_title_hbox = HBoxContainer.new() + volume_vbox.add_child(volume_title_hbox) + var volume_label = Label.new() volume_label.text = "音量 (dB)" - volume_vbox.add_child(volume_label) - - var volume_hbox = HBoxContainer.new() - volume_vbox.add_child(volume_hbox) + volume_title_hbox.add_child(volume_label) + + # 重置音量按钮 + var reset_volumn_button = Button.new() + reset_volumn_button.text = "重置音量" + reset_volumn_button.pressed.connect(reset_volumn.bind(sfx_node)) + volume_title_hbox.add_child(reset_volumn_button) + + var volume_slider_hbox = HBoxContainer.new() + volume_vbox.add_child(volume_slider_hbox) var volume_slider = HSlider.new() volume_slider.min_value = -60.0 @@ -99,20 +123,20 @@ func create_sfx_item(sfx_node: Node): volume_slider.step = 0.1 volume_slider.value = sfx_node.volume_db volume_slider.custom_minimum_size.x = 200 - volume_hbox.add_child(volume_slider) + volume_slider_hbox.add_child(volume_slider) var volume_value_label = Label.new() volume_value_label.text = str(snapped(sfx_node.volume_db, 0.1)) volume_value_label.custom_minimum_size.x = 50 - volume_hbox.add_child(volume_value_label) + volume_slider_hbox.add_child(volume_value_label) # 双向绑定音量 volume_slider.value_changed.connect(func(value): sfx_node.volume_db = value volume_value_label.text = str(snapped(value, 0.1)) - save_node_config(sfx_node.name, "volume_db", value) + save_node_config(sfx_node.get_path(), "volume_db", value) ) - + # Stream 信息和控制 var stream_vbox = VBoxContainer.new() controls_hbox.add_child(stream_vbox) @@ -128,6 +152,7 @@ func create_sfx_item(sfx_node: Node): stream_name_label.custom_minimum_size.x = 150 _set_stream_name_label(sfx_node, stream_name_label) stream_hbox.add_child(stream_name_label) + # 预览播放按钮 var preview_button = Button.new() @@ -138,11 +163,11 @@ func create_sfx_item(sfx_node: Node): # 恢复默认按钮 if sfx_node.stream_was_replaced(): - var reset_button = Button.new() - reset_button.text = "🗑️" - reset_button.custom_minimum_size = Vector2(30, 30) - reset_button.pressed.connect(reset_audio.bind(sfx_node)) - stream_hbox.add_child(reset_button) + var reset_btn = Button.new() + reset_btn.text = "恢复默认音频" + reset_btn.custom_minimum_size = Vector2(30, 30) + reset_btn.pressed.connect(reset_audio.bind(sfx_node)) + stream_hbox.add_child(reset_btn) # 3. 上传文件按钮 var upload_button = Button.new() @@ -166,6 +191,12 @@ func _set_stream_name_label(sfx_node:Sfx, stream_name_label:Label) -> void: stream_name_label.text = "无音频文件" +func reset_volumn(sfx_node: Sfx): + sfx_node.volume_db = sfx_node.default_db + save_config() + refresh_ui() + + func preview_audio(sfx_node: Sfx): if sfx_node.stream: preview_player.stream = sfx_node.stream @@ -175,7 +206,7 @@ func preview_audio(sfx_node: Sfx): func reset_audio(sfx_node: Sfx): sfx_node.reset_original_stream() - config_data.erase(sfx_node.name) + config_data.erase(sfx_node.get_path()) save_config() refresh_ui() @@ -220,7 +251,7 @@ func copy_and_load_audio_file(source_path: String, sfx_node: Node, stream_label: if new_stream: sfx_node.replace_stream(new_stream) stream_label.text = file_name - save_node_config(sfx_node.name, "stream", target_path) + save_node_config(sfx_node.get_path(), "stream", target_path) print("音频文件已更新: ", sfx_node.name, " -> ", file_name) else: push_error("无法加载音频文件: " + target_path) @@ -228,10 +259,10 @@ func copy_and_load_audio_file(source_path: String, sfx_node: Node, stream_label: # 4. 配置保存与加载 -func save_node_config(node_name: String, property: String, value): - if not config_data.has(node_name): - config_data[node_name] = {} - config_data[node_name][property] = value +func save_node_config(node_path: String, property: String, value): + if not config_data.has(node_path): + config_data[node_path] = {} + config_data[node_path][property] = value save_config() func save_config(): @@ -260,8 +291,9 @@ func load_config(): func apply_config(): for sfx_node in sfx_nodes: - if config_data.has(sfx_node.name): - var node_config = config_data[sfx_node.name] + var sfx_path = sfx_node.get_path() + if config_data.has(sfx_path): + var node_config = config_data[sfx_path] if node_config.has("volume_db"): sfx_node.volume_db = node_config["volume_db"] if node_config.has("stream"): diff --git a/scene/entity/audio/sfx.gd b/scene/entity/audio/sfx.gd index d901d5ae..a765f165 100644 --- a/scene/entity/audio/sfx.gd +++ b/scene/entity/audio/sfx.gd @@ -35,6 +35,8 @@ func _ready() -> void: SceneManager.ground_transition_pre_paused.connect(_on_ground_transition_pre_paused) SceneManager.pause_counter_updated.connect(_on_pause_counter_updated) +var playing_on_debugging_paused = false + func _on_pause_counter_updated() -> void: _set_up_process_mode_by_mode() @@ -45,6 +47,8 @@ func _set_up_process_mode_by_mode(): if mode == "场景背景音" and not SceneManager.pause_counter_arr.has("debugging"): process_mode = Node.PROCESS_MODE_ALWAYS else: + if SceneManager.pause_counter_arr.has("debugging"): + playing_on_debugging_paused = playing process_mode = Node.PROCESS_MODE_PAUSABLE @@ -69,9 +73,8 @@ func reset_original_stream(ignore_null := true): func replace_stream(new_stream: AudioStream) -> void: - stop() stream = new_stream - if autoplay and is_node_ready(): + if (playing_on_debugging_paused or autoplay) and is_node_ready(): play() diff --git a/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn b/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn index f89a1509..6502aa9b 100644 --- a/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn +++ b/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn @@ -169,6 +169,7 @@ script = ExtResource("4_qq2uh") loop = true [node name="Sfx猫鼠游戏" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"] +process_mode = 1 stream = SubResource("AudioStreamInteractive_af0pm") volume_db = -17.0 bus = &"game_sfx" diff --git a/scene/ground/scene/c01/s07_书店外.tscn b/scene/ground/scene/c01/s07_书店外.tscn index 2ea2c4cb..25a79248 100644 --- a/scene/ground/scene/c01/s07_书店外.tscn +++ b/scene/ground/scene/c01/s07_书店外.tscn @@ -69,13 +69,13 @@ player_y = 55 script = ExtResource("2_dhaq4") [node name="环境音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 stream = ExtResource("3_na2nu") volume_db = -4.0 autoplay = true bus = &"game_sfx" script = ExtResource("4_c7jb6") mode = "场景背景音" -"自动开始" = true "循环播放" = true "感应玩家操作" = false metadata/_custom_type_script = "uid://rq6w1vuhuq1m" diff --git a/scene/ground/scene/c01/s08_书店.tscn b/scene/ground/scene/c01/s08_书店.tscn index 48f4c44a..8ac2a0cf 100644 --- a/scene/ground/scene/c01/s08_书店.tscn +++ b/scene/ground/scene/c01/s08_书店.tscn @@ -42,24 +42,24 @@ libraries = { script = ExtResource("2_0lque") [node name="环境音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 stream = ExtResource("3_0x288") volume_db = -8.0 autoplay = true bus = &"game_sfx" script = ExtResource("4_p6k3c") mode = "场景背景音" -"自动开始" = true "循环播放" = true "感应玩家操作" = false metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="诡异环境音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] +process_mode = 1 stream = ExtResource("5_eerhd") volume_db = -7.0 bus = &"game_sfx" script = ExtResource("4_p6k3c") mode = "场景背景音" -"自动开始" = false "循环播放" = true "感应玩家操作" = false metadata/_custom_type_script = "uid://rq6w1vuhuq1m" diff --git a/scene/ground/scene/c01/s11_黄包车演出.tscn b/scene/ground/scene/c01/s11_黄包车演出.tscn index 2130f700..4afdfd58 100644 --- a/scene/ground/scene/c01/s11_黄包车演出.tscn +++ b/scene/ground/scene/c01/s11_黄包车演出.tscn @@ -156,12 +156,12 @@ bus = &"game_sfx" script = ExtResource("3_vx53v") [node name="黄包车背景音效" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] +process_mode = 1 stream = SubResource("AudioStreamSynchronized_s11la") autoplay = true bus = &"game_sfx" script = ExtResource("3_vx53v") mode = "场景背景音" -"自动开始" = true "循环播放" = true "感应玩家操作" = false metadata/_custom_type_script = "uid://rq6w1vuhuq1m" diff --git a/scene/ground/scene/c02/s01_公寓门口.tscn b/scene/ground/scene/c02/s01_公寓门口.tscn index c5d23a58..08ff5e86 100644 --- a/scene/ground/scene/c02/s01_公寓门口.tscn +++ b/scene/ground/scene/c02/s01_公寓门口.tscn @@ -24,6 +24,7 @@ player_y = 60 script = ExtResource("2_jfumy") [node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 stream = ExtResource("4_ev3cr") volume_db = -5.0 autoplay = true @@ -35,6 +36,7 @@ mode = "场景背景音" metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="Sfx背景虫鸣" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] +process_mode = 1 stream = ExtResource("6_ev3cr") volume_db = -10.0 autoplay = true diff --git a/scene/ground/scene/c02/s02_过道.tscn b/scene/ground/scene/c02/s02_过道.tscn index c3ea34ae..15418554 100644 --- a/scene/ground/scene/c02/s02_过道.tscn +++ b/scene/ground/scene/c02/s02_过道.tscn @@ -7,7 +7,7 @@ [ext_resource type="Texture2D" uid="uid://5428j51dwarc" path="res://asset/art/scene/c02/s02_大门过道/bg_过道背景.png" id="3_gjwum"] [ext_resource type="AudioStream" uid="uid://o7fj0r0fbm1h" path="res://asset/audio/sfx/交互/第一章/sfx_冷飕飕.ogg" id="4_36l5t"] [ext_resource type="SpriteFrames" uid="uid://b7fhheih1hbvf" path="res://config/animation/entity_sprite_frames.tres" id="4_wbif8"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="5_36l5t"] +[ext_resource type="AudioStream" uid="uid://bjwguxsoehrne" path="res://asset/audio/sfx/环境音/第一章/楼道场景2.ogg" id="5_2lo60"] [ext_resource type="Texture2D" uid="uid://r0n7qy4kr3w2" path="res://asset/art/ui/action_mark/UI场景切换.png" id="5_m1xet"] [ext_resource type="Texture2D" uid="uid://b8pcnqvdddo5g" path="res://asset/art/prop/c02/海报特写/除鼠二杰.png" id="7_jg8g0"] [ext_resource type="Texture2D" uid="uid://cvgw2mxrlr6io" path="res://asset/art/scene/c02/旧版/s02_走道/ux_进门鼠疫海报yz.png" id="7_wdwbi"] @@ -59,14 +59,22 @@ libraries = { script = ExtResource("2_5p8ev") [node name="冷飕飕Sfx" parent="Ground/AnimationPlayer" index="0" instance=ExtResource("3_fvldj")] +process_mode = 1 stream = ExtResource("4_36l5t") volume_db = -10.0 mode = "交互与效果音" -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="1"] -script = ExtResource("5_36l5t") -autoplay_group = &"c02_楼道2" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] +process_mode = 1 +stream = ExtResource("5_2lo60") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("14_jg8g0") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] self_modulate = Color(0.831373, 0.886275, 0.956863, 1) diff --git a/scene/ground/scene/c02/s03_院子.gd b/scene/ground/scene/c02/s03_院子.gd index e6cb3e3f..ca443aa9 100644 --- a/scene/ground/scene/c02/s03_院子.gd +++ b/scene/ground/scene/c02/s03_院子.gd @@ -56,7 +56,8 @@ func _on_ground_ready() -> void: new_bg.modulate.a = 1.0 # 火灾开始后,无需 enable counter.get_node("点燃").modulate.a = 1.0 - $VibeSfx氛围.switch_to("c02_火灾") + $"Sfx背景音".easing_kill() + $"Sfx背景火灾".play() $"../DirectionalLight2D".energy = 0 eavesdrop_window = $"../DeployLayer/李氏赖子房间人影" madman_npc = $"../DeployLayer/Npc井边疯子" @@ -221,7 +222,8 @@ func _setup_bully_or_burning(reenter_scene := false): else: bully_layer.visible = false burning_layer.visible = true - $VibeSfx氛围.switch_to("c02_火灾") + $"Sfx背景音".easing_kill() + $"Sfx背景火灾".play() $"../DeployLayer/霸凌/f1/Sfx2D霸凌童谣".easing_kill() bully_layer.get_node("Ambush点火游戏阻挡右移").enabled = false bully_layer.get_node("wall/CollisionShape2D").disabled = true diff --git a/scene/ground/scene/c02/s03_院子.tscn b/scene/ground/scene/c02/s03_院子.tscn index 78fc4f94..371e331a 100644 --- a/scene/ground/scene/c02/s03_院子.tscn +++ b/scene/ground/scene/c02/s03_院子.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=82 format=3 uid="uid://djc2uaefhmu7"] +[gd_scene load_steps=83 format=3 uid="uid://djc2uaefhmu7"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_0dylx"] [ext_resource type="Script" uid="uid://dsp5plrdkrsd7" path="res://scene/ground/scene/c02/s03_院子.gd" id="2_dt5aj"] @@ -7,6 +7,7 @@ [ext_resource type="SpriteFrames" uid="uid://3nas025c2c5u" path="res://asset/art/gif/c02_杂项/c02_杂项_frames.tres" id="4_gd6xp"] [ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_ygnci"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="5_00b7a"] +[ext_resource type="AudioStream" uid="uid://s7uigovfp5g3" path="res://asset/audio/sfx/环境音/第一章/火灾演出.ogg" id="5_fxne6"] [ext_resource type="AudioStream" uid="uid://bk5cdc06s8x10" path="res://asset/audio/sfx/bgm/第一章/打开铁门后不循环背景音.ogg" id="5_qt2qg"] [ext_resource type="Texture2D" uid="uid://f8yjp5ggr8qw" path="res://asset/art/scene/c02/s03_公寓一楼院子/算卦布.png" id="6_1tart"] [ext_resource type="Texture2D" uid="uid://0uh6qaalhqju" path="res://asset/art/scene/c02/s11_一楼火灾/总背景/bg_院子1楼火灾.png" id="6_d7h4s"] @@ -285,7 +286,18 @@ libraries = { } script = ExtResource("2_dt5aj") -[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +[node name="Sfx背景火灾" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("5_fxne6") +bus = &"game_sfx" +script = ExtResource("4_ygnci") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" + +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] +process_mode = 1 stream = ExtResource("3_2b6vx") volume_db = -12.0 autoplay = true @@ -296,33 +308,33 @@ mode = "场景背景音" "感应玩家操作" = false metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="Sfx闷雷" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] +[node name="Sfx闷雷" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"] stream = ExtResource("6_vddfx") bus = &"game_sfx" script = ExtResource("4_ygnci") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="Sfx打开铁门后" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"] +[node name="Sfx打开铁门后" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="3"] stream = ExtResource("5_qt2qg") volume_db = -20.0 bus = &"game_sfx" script = ExtResource("4_ygnci") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="Sfx小鞋落地" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="3"] +[node name="Sfx小鞋落地" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="4"] stream = ExtResource("7_df1yo") bus = &"game_sfx" script = ExtResource("4_ygnci") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="Sfx小蝉哼歌" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="4"] +[node name="Sfx小蝉哼歌" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="5"] stream = ExtResource("6_jhod7") volume_db = 16.0 bus = &"game_sfx" script = ExtResource("4_ygnci") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="Sfx牵手演出氛围音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="5"] +[node name="Sfx牵手演出氛围音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="6"] stream = ExtResource("9_2b6vx") bus = &"game_sfx" script = ExtResource("4_ygnci") diff --git a/scene/ground/scene/c02/s04_保卫科.tscn b/scene/ground/scene/c02/s04_保卫科.tscn index 6a53563c..e021873b 100644 --- a/scene/ground/scene/c02/s04_保卫科.tscn +++ b/scene/ground/scene/c02/s04_保卫科.tscn @@ -1,11 +1,12 @@ -[gd_scene load_steps=23 format=3 uid="uid://bivc5cdap370p"] +[gd_scene load_steps=24 format=3 uid="uid://bivc5cdap370p"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_2jej0"] [ext_resource type="Script" uid="uid://dmhh4g47bdxxy" path="res://scene/ground/scene/c02/s04_保卫科.gd" id="2_jyere"] [ext_resource type="Texture2D" uid="uid://7jvg2flkapj3" path="res://asset/art/scene/c02/s04_保卫科/bg_保卫科.png" id="3_66gue"] +[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_g8amr"] +[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_cq2m4"] [ext_resource type="SpriteFrames" uid="uid://c2sjavnptjn" path="res://asset/art/gif/c02_保卫科/c02_保卫科_frames.tres" id="4_svuj3"] [ext_resource type="Texture2D" uid="uid://bnyf8m63ltgh0" path="res://asset/art/scene/c02/s04_保卫科/l_香.png" id="5_cy26p"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="5_g8amr"] [ext_resource type="PackedScene" uid="uid://dqkxiqbq83cmq" path="res://scene/entity/closeup.tscn" id="6_66gue"] [ext_resource type="PackedScene" uid="uid://b8i6tqwdvvddy" path="res://scene/ground/script/c02/花名册.tscn" id="6_fvlg0"] [ext_resource type="Texture2D" uid="uid://cs14llkvr3fg8" path="res://asset/art/scene/c02/s04_保卫科/e_弹珠墙面涂鸦提示.png" id="6_gk1h4"] @@ -33,10 +34,17 @@ player_y = 60 [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_jyere") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("5_g8amr") -autoplay_group = &"c02_房间里1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_g8amr") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_cq2m4") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] light_mask = 5 diff --git a/scene/ground/scene/c02/s05_一楼内侧楼道.tscn b/scene/ground/scene/c02/s05_一楼内侧楼道.tscn index 72c29857..af1de602 100644 --- a/scene/ground/scene/c02/s05_一楼内侧楼道.tscn +++ b/scene/ground/scene/c02/s05_一楼内侧楼道.tscn @@ -2,7 +2,7 @@ [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_6w6et"] [ext_resource type="Script" uid="uid://dydpmjpcvt3v1" path="res://scene/ground/scene/c02/s05_一楼内侧楼道.gd" id="2_70lf6"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_laquj"] +[ext_resource type="AudioStream" uid="uid://blf1rtu71vy17" path="res://asset/audio/sfx/环境音/第一章/楼道场景1.ogg" id="3_74b3r"] [ext_resource type="Texture2D" uid="uid://dbtepltemtmy2" path="res://asset/art/scene/c02/s05_一楼内侧楼道/bg_楼道背景.png" id="3_rcuxq"] [ext_resource type="AudioStream" uid="uid://d3tnbdx2j4tmy" path="res://asset/audio/sfx/bgm/第一章/sfx_一楼楼道记忆闪回.ogg" id="4_74b3r"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_tueh3"] @@ -113,10 +113,17 @@ libraries = { } script = ExtResource("2_70lf6") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_laquj") -autoplay_group = &"c02_楼道1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_74b3r") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("5_74b3r") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="Sfx记忆闪回音效" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] stream = ExtResource("4_74b3r") diff --git a/scene/ground/scene/c02/s06_二楼.tscn b/scene/ground/scene/c02/s06_二楼.tscn index 99e35a88..16909be8 100644 --- a/scene/ground/scene/c02/s06_二楼.tscn +++ b/scene/ground/scene/c02/s06_二楼.tscn @@ -2,7 +2,7 @@ [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_qkymk"] [ext_resource type="Script" uid="uid://cbt0ubygchxvv" path="res://scene/ground/scene/c02/s06_二楼.gd" id="2_4dg6u"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_h3h1a"] +[ext_resource type="AudioStream" uid="uid://bjwguxsoehrne" path="res://asset/audio/sfx/环境音/第一章/楼道场景2.ogg" id="3_lipxo"] [ext_resource type="Texture2D" uid="uid://6ol2om68cd1q" path="res://asset/art/scene/c02/s06_二楼楼道/bg_背景.png" id="3_och2w"] [ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_2e08x"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_haidv"] @@ -898,10 +898,17 @@ libraries = { } script = ExtResource("2_4dg6u") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_h3h1a") -autoplay_group = &"c02_楼道2" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_lipxo") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_2e08x") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="Sfx翻找东西" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] stream = ExtResource("5_lh55k") diff --git a/scene/ground/scene/c02/s07_二楼内侧楼道.tscn b/scene/ground/scene/c02/s07_二楼内侧楼道.tscn index 0855516d..10cfcd04 100644 --- a/scene/ground/scene/c02/s07_二楼内侧楼道.tscn +++ b/scene/ground/scene/c02/s07_二楼内侧楼道.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=19 format=3 uid="uid://t4xjt774ngwh"] +[gd_scene load_steps=20 format=3 uid="uid://t4xjt774ngwh"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_oao56"] [ext_resource type="Script" uid="uid://cnjdxjni5v3cs" path="res://scene/ground/scene/c02/s07_二楼内侧楼道.gd" id="2_t0s64"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_geise"] +[ext_resource type="AudioStream" uid="uid://bjwguxsoehrne" path="res://asset/audio/sfx/环境音/第一章/楼道场景2.ogg" id="3_e4bwj"] [ext_resource type="Texture2D" uid="uid://u7rp66mboqq4" path="res://asset/art/scene/c02/s07_二楼内侧楼道/bg_背景.png" id="3_t0s64"] +[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_4anfx"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_5krke"] [ext_resource type="Texture2D" uid="uid://bim6w1xp1a4bg" path="res://asset/art/scene/c02/s07_二楼内侧楼道/锡箔墙面涂鸦提示.png" id="5_6ivku"] [ext_resource type="PackedScene" uid="uid://xovlfee503a4" path="res://scene/ground/script/c02/小手讨东西.tscn" id="6_5krke"] @@ -28,10 +29,17 @@ player_y = 60 [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_t0s64") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_geise") -autoplay_group = &"c02_楼道2" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_e4bwj") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_4anfx") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("3_t0s64") diff --git a/scene/ground/scene/c02/s08_瞎子卧室.tscn b/scene/ground/scene/c02/s08_瞎子卧室.tscn index b2964e13..def1911e 100644 --- a/scene/ground/scene/c02/s08_瞎子卧室.tscn +++ b/scene/ground/scene/c02/s08_瞎子卧室.tscn @@ -3,10 +3,10 @@ [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_judx3"] [ext_resource type="Script" uid="uid://hbbgymjs5xte" path="res://scene/ground/scene/c02/s08_瞎子卧室.gd" id="2_m4uw8"] [ext_resource type="Texture2D" uid="uid://v3sj36aijq5b" path="res://asset/art/scene/c02/s08_瞎子卧室/bg_瞎子卧室.png" id="3_iares"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_quq80"] [ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="3_t3h08"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_1ws4i"] [ext_resource type="Texture2D" uid="uid://vqyhgyka3sfo" path="res://asset/art/scene/c02/s08_瞎子卧室/瞎子卧室前景.png" id="4_gx8oy"] +[ext_resource type="AudioStream" uid="uid://o57tyriodr0c" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里2.ogg" id="4_quq80"] [ext_resource type="AudioStream" uid="uid://dk3e1w3n2snur" path="res://asset/audio/sfx/旧版/c02/纸人出现.ogg" id="5_0qeqe"] [ext_resource type="Texture2D" uid="uid://b5pwb4fm46sad" path="res://asset/art/scene/c02/s08_瞎子卧室/e_墙上纸张.png" id="5_f6mma"] [ext_resource type="Texture2D" uid="uid://7ay1ttob8qwm" path="res://asset/art/scene/c02/s08_瞎子卧室/e_床板.png" id="5_vjjde"] @@ -111,10 +111,17 @@ libraries = { } script = ExtResource("2_m4uw8") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_quq80") -autoplay_group = &"c02_房间里2" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("4_quq80") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("3_t3h08") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="Sfx癞子对视惊吓" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] stream = ExtResource("5_0qeqe") diff --git a/scene/ground/scene/c02/s09_裂缝.tscn b/scene/ground/scene/c02/s09_裂缝.tscn index 42ac9977..20bb75ef 100644 --- a/scene/ground/scene/c02/s09_裂缝.tscn +++ b/scene/ground/scene/c02/s09_裂缝.tscn @@ -186,7 +186,6 @@ autoplay = true bus = &"game_sfx" script = ExtResource("4_qjenp") mode = "场景背景音" -"自动开始" = true "循环播放" = true "感应玩家操作" = false metadata/_custom_type_script = "uid://rq6w1vuhuq1m" @@ -196,7 +195,6 @@ stream = ExtResource("5_husb8") bus = &"game_sfx" script = ExtResource("4_qjenp") mode = "场景背景音" -"自动开始" = false "循环播放" = true "感应玩家操作" = false metadata/_custom_type_script = "uid://rq6w1vuhuq1m" diff --git a/scene/ground/scene/c02/s10_空房间.tscn b/scene/ground/scene/c02/s10_空房间.tscn index 0f669f95..a4472892 100644 --- a/scene/ground/scene/c02/s10_空房间.tscn +++ b/scene/ground/scene/c02/s10_空房间.tscn @@ -2,8 +2,8 @@ [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_w7j0m"] [ext_resource type="Script" uid="uid://dkkey7qillk15" path="res://scene/ground/scene/c02/s10_空房间.gd" id="2_egtqi"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_kqj5r"] [ext_resource type="Texture2D" uid="uid://molvyfyy63ik" path="res://asset/art/scene/c02/s10_空房间/bg_空房间.png" id="3_ox8et"] +[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="4_alb6s"] [ext_resource type="AudioStream" uid="uid://dfni8aakmmp00" path="res://asset/audio/sfx/旧版/c02/红色印记出现.ogg" id="4_nx6jy"] [ext_resource type="AudioStream" uid="uid://bhaws2ungqaf5" path="res://asset/audio/sfx/交互/角色/sfx_哼歌.ogg" id="5_8cwaw"] [ext_resource type="PackedScene" uid="uid://cw3q5pvciumil" path="res://scene/entity/interactable.tscn" id="5_ylhfc"] @@ -85,10 +85,17 @@ player_y = 60 [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_egtqi") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_kqj5r") -autoplay_group = &"c02_房间里1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("4_alb6s") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("6_6uftv") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="Sfx小蝉出现" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] stream = ExtResource("4_nx6jy") diff --git a/scene/ground/scene/c02/s12_盒子猫.tscn b/scene/ground/scene/c02/s12_盒子猫.tscn index 653908a9..caf4ed52 100644 --- a/scene/ground/scene/c02/s12_盒子猫.tscn +++ b/scene/ground/scene/c02/s12_盒子猫.tscn @@ -6,7 +6,7 @@ [ext_resource type="Texture2D" uid="uid://yn00uls1kvn3" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_初始.png" id="3_oskpk"] [ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_r3hvb"] [ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="4_vv3sh"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="5_72mc1"] +[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="5_72mc1"] [ext_resource type="SpriteFrames" uid="uid://b85gyfhk1mg6r" path="res://asset/art/gif/c02_盒子猫/c02_盒子猫_frames.tres" id="5_ycgng"] [node name="S12" type="Node2D"] @@ -26,10 +26,17 @@ bus = &"game_sfx" script = ExtResource("4_r3hvb") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="1"] -script = ExtResource("5_72mc1") -autoplay_group = &"c02_房间里1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"] +process_mode = 1 +stream = ExtResource("5_72mc1") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_r3hvb") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("3_oskpk") diff --git a/scene/ground/scene/c02/s13_盒子猫二楼.tscn b/scene/ground/scene/c02/s13_盒子猫二楼.tscn index 78943471..b07d8f00 100644 --- a/scene/ground/scene/c02/s13_盒子猫二楼.tscn +++ b/scene/ground/scene/c02/s13_盒子猫二楼.tscn @@ -7,7 +7,7 @@ [ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_yywsi"] [ext_resource type="AudioStream" uid="uid://b8sbtn3l37uh" path="res://asset/audio/sfx/旧版/c02/红屏.ogg" id="5_yywsi"] [ext_resource type="Texture2D" uid="uid://csrfyvaufo1wb" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/l_瞎子理发店光.png" id="6_gge8e"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="6_kmk38"] +[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="6_kmk38"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="6_yywsi"] [ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="7_u2fv1"] [ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="9_yywsi"] @@ -36,10 +36,17 @@ bus = &"game_sfx" script = ExtResource("4_yywsi") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="2"] -script = ExtResource("6_kmk38") -autoplay_group = &"c02_房间里1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"] +process_mode = 1 +stream = ExtResource("6_kmk38") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_yywsi") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("3_miykx") diff --git a/scene/ground/scene/c02/s14_盒子猫二楼内侧.tscn b/scene/ground/scene/c02/s14_盒子猫二楼内侧.tscn index 89ec1977..e2cc5e0b 100644 --- a/scene/ground/scene/c02/s14_盒子猫二楼内侧.tscn +++ b/scene/ground/scene/c02/s14_盒子猫二楼内侧.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=8 format=3 uid="uid://d0p4x5st2r315"] +[gd_scene load_steps=9 format=3 uid="uid://d0p4x5st2r315"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_cr1hi"] [ext_resource type="Script" uid="uid://bjisuntcem2lv" path="res://scene/ground/scene/c02/s14_盒子猫二楼内侧.gd" id="2_o47bv"] [ext_resource type="Texture2D" uid="uid://y0e47513ca22" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_二楼内侧楼道(粉笔画).png" id="3_cr1hi"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_idisw"] +[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_kss0n"] +[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_3yfjs"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_o47bv"] [ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="5_cr1hi"] [ext_resource type="PackedScene" uid="uid://dewbg4phd8c17" path="res://scene/ground/script/c02/追猫猪头怪.tscn" id="5_o47bv"] @@ -19,10 +20,17 @@ footstep_type = "盒子猫" [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_o47bv") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_idisw") -autoplay_group = &"c02_房间里1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_kss0n") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_3yfjs") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("3_cr1hi") diff --git a/scene/ground/scene/c02/s15_盒子猫一楼内侧.tscn b/scene/ground/scene/c02/s15_盒子猫一楼内侧.tscn index 96bbc946..7d5cbefb 100644 --- a/scene/ground/scene/c02/s15_盒子猫一楼内侧.tscn +++ b/scene/ground/scene/c02/s15_盒子猫一楼内侧.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=7 format=3 uid="uid://b21p53g42j2nt"] +[gd_scene load_steps=8 format=3 uid="uid://b21p53g42j2nt"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_qxg0l"] [ext_resource type="Script" uid="uid://ebaq235h32fd" path="res://scene/ground/scene/c02/s15_盒子猫一楼内侧.gd" id="2_etqjj"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_etqjj"] +[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_etqjj"] [ext_resource type="Texture2D" uid="uid://c4eb71kdnqy3y" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_一楼内侧楼道(粉笔画).png" id="3_qxg0l"] +[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_k187n"] [ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="5_isic3"] [ext_resource type="PackedScene" uid="uid://dewbg4phd8c17" path="res://scene/ground/script/c02/追猫猪头怪.tscn" id="6_etqjj"] @@ -18,10 +19,17 @@ footstep_type = "盒子猫" [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_etqjj") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_etqjj") -autoplay_group = &"c02_房间里1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_etqjj") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_k187n") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("3_qxg0l") diff --git a/scene/ground/scene/c02/s16_盒子猫三楼内侧.tscn b/scene/ground/scene/c02/s16_盒子猫三楼内侧.tscn index c9af93a8..f5fb5130 100644 --- a/scene/ground/scene/c02/s16_盒子猫三楼内侧.tscn +++ b/scene/ground/scene/c02/s16_盒子猫三楼内侧.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=9 format=3 uid="uid://22hc3oe8t0id"] +[gd_scene load_steps=10 format=3 uid="uid://22hc3oe8t0id"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_umyae"] [ext_resource type="Script" uid="uid://dx2w5v1erjyls" path="res://scene/ground/scene/c02/s16_盒子猫三楼内侧.gd" id="2_tmnwc"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_r8qm5"] +[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_7w00y"] [ext_resource type="Texture2D" uid="uid://by4ymjhnma8c6" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_三楼内侧楼道(粉笔画).png" id="3_tmnwc"] +[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_1h6hi"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_qkv3g"] [ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="5_qkv3g"] [ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="5_tmnwc"] @@ -20,10 +21,17 @@ footstep_type = "盒子猫" [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_tmnwc") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_r8qm5") -autoplay_group = &"c02_房间里1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_7w00y") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_1h6hi") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("3_tmnwc") diff --git a/scene/ground/scene/c02/s17_盒子猫三楼.tscn b/scene/ground/scene/c02/s17_盒子猫三楼.tscn index 7eb2af9e..0a1a2bd7 100644 --- a/scene/ground/scene/c02/s17_盒子猫三楼.tscn +++ b/scene/ground/scene/c02/s17_盒子猫三楼.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=9 format=3 uid="uid://cbr6gbgrl2wb1"] +[gd_scene load_steps=10 format=3 uid="uid://cbr6gbgrl2wb1"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_e436a"] [ext_resource type="Script" uid="uid://bkkhxiyblu2lo" path="res://scene/ground/scene/c02/s17_盒子猫三楼.gd" id="2_e436a"] +[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_4yexs"] [ext_resource type="Texture2D" uid="uid://iyeqjguyrhog" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_三楼楼道(粉笔画).png" id="3_e436a"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_uua76"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_e436a"] +[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_m6dyn"] [ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="4_n3bxc"] [ext_resource type="PackedScene" uid="uid://dewbg4phd8c17" path="res://scene/ground/script/c02/追猫猪头怪.tscn" id="6_pfgbg"] [ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="8_m6dyn"] @@ -20,10 +21,17 @@ footstep_type = "盒子猫" [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_e436a") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_uua76") -autoplay_group = &"c02_房间里1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_4yexs") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_m6dyn") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("3_e436a") diff --git a/scene/ground/scene/c02/s18_盒子猫一楼.tscn b/scene/ground/scene/c02/s18_盒子猫一楼.tscn index 834cb2a1..3f721402 100644 --- a/scene/ground/scene/c02/s18_盒子猫一楼.tscn +++ b/scene/ground/scene/c02/s18_盒子猫一楼.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=8 format=3 uid="uid://d27gv3pbkn4b8"] +[gd_scene load_steps=9 format=3 uid="uid://d27gv3pbkn4b8"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_4bsvj"] [ext_resource type="Script" uid="uid://b3mak700k2qwt" path="res://scene/ground/scene/c02/s18_盒子猫一楼.gd" id="2_4bsvj"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_4bsvj"] +[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_bbmua"] [ext_resource type="Texture2D" uid="uid://ttocw3erg8jv" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_一楼楼道(粉笔画).png" id="3_owpnf"] +[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_po2lv"] [ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="5_emyx1"] [ext_resource type="PackedScene" uid="uid://dewbg4phd8c17" path="res://scene/ground/script/c02/追猫猪头怪.tscn" id="6_xoyld"] [ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="7_8eo7o"] @@ -19,10 +20,17 @@ footstep_type = "盒子猫" [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_4bsvj") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_4bsvj") -autoplay_group = &"c02_房间里1" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_bbmua") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_po2lv") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("3_owpnf") diff --git a/scene/ground/scene/c03/s01_三楼.tscn b/scene/ground/scene/c03/s01_三楼.tscn index 573e3186..d17d802e 100644 --- a/scene/ground/scene/c03/s01_三楼.tscn +++ b/scene/ground/scene/c03/s01_三楼.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=32 format=3 uid="uid://dlrbhfvnd3cs0"] +[gd_scene load_steps=33 format=3 uid="uid://dlrbhfvnd3cs0"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_eb2op"] [ext_resource type="Script" uid="uid://c0rh2n36ait6i" path="res://scene/ground/scene/c03/s01_三楼.gd" id="2_ow08b"] -[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_lb1oo"] +[ext_resource type="AudioStream" uid="uid://bjwguxsoehrne" path="res://asset/audio/sfx/环境音/第一章/楼道场景2.ogg" id="3_hmme5"] +[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_1ebn8"] [ext_resource type="Texture2D" uid="uid://cpjd3dqri51fq" path="res://asset/art/scene/c03/s01_三楼/bg_三楼走廊.png" id="4_ow08b"] [ext_resource type="Texture2D" uid="uid://b7t2sfe5ugtsc" path="res://asset/art/scene/c03/引导纸人/指引纸人3.png" id="5_fnwup"] [ext_resource type="Texture2D" uid="uid://djoft6600kly6" path="res://asset/art/scene/c03/s01_三楼/fg_前景.png" id="5_ow08b"] @@ -183,10 +184,17 @@ libraries = { } script = ExtResource("2_ow08b") -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] -script = ExtResource("3_lb1oo") -autoplay_group = &"c02_楼道2" -metadata/_custom_type_script = "uid://cpejxlfni6n52" +[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] +process_mode = 1 +stream = ExtResource("3_hmme5") +volume_db = -5.0 +autoplay = true +bus = &"game_sfx" +script = ExtResource("4_1ebn8") +mode = "场景背景音" +"循环播放" = true +"感应玩家操作" = false +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" [node name="BGSprite2D" parent="Ground" index="2"] light_mask = 5