2025-05-13 11:45:33 +00:00
|
|
|
|
@tool
|
|
|
|
|
|
|
|
|
|
extends Interactable2D
|
|
|
|
|
class_name Closeup2D
|
|
|
|
|
|
|
|
|
|
# 退出信号,默认 arg 为 null,可能是一个 bool 值,从 packed_scene 的 exit 信号中传递过来
|
|
|
|
|
signal exit(arg)
|
|
|
|
|
|
|
|
|
|
@export var packed_scene: PackedScene
|
2025-06-24 17:52:30 +00:00
|
|
|
|
@export var quit_closeup_on_escape := true
|
2025-07-04 13:02:27 +00:00
|
|
|
|
@export_tool_button("新建特写场景") var create_closeup_scene = _create_scene_with_script
|
|
|
|
|
|
2025-05-13 11:45:33 +00:00
|
|
|
|
var current_child: Node
|
|
|
|
|
|
2025-06-24 20:12:24 +00:00
|
|
|
|
|
2025-05-13 11:45:33 +00:00
|
|
|
|
func _ready() -> void:
|
|
|
|
|
super._ready()
|
|
|
|
|
if Engine.is_editor_hint():
|
|
|
|
|
return
|
2025-06-25 17:53:16 +00:00
|
|
|
|
interacted.connect(display)
|
2025-06-11 05:43:36 +00:00
|
|
|
|
|
2025-05-13 11:45:33 +00:00
|
|
|
|
|
2025-05-14 20:43:55 +00:00
|
|
|
|
# 可以直接调用
|
|
|
|
|
func display() -> void:
|
2025-05-13 11:45:33 +00:00
|
|
|
|
if current_child:
|
2025-06-28 16:11:21 +00:00
|
|
|
|
return
|
2025-05-13 11:45:33 +00:00
|
|
|
|
if packed_scene:
|
2025-06-28 16:11:21 +00:00
|
|
|
|
if GlobalConfig.DEBUG:
|
|
|
|
|
print("[" + name + "] call lock")
|
2025-06-28 13:42:20 +00:00
|
|
|
|
SceneManager.lock_player(0, action_key)
|
2025-06-13 08:03:19 +00:00
|
|
|
|
# 展示时,禁用 sign_mark 的输入
|
|
|
|
|
sign_mark.pass_unhandled_input = true
|
2025-05-13 11:45:33 +00:00
|
|
|
|
current_child = packed_scene.instantiate()
|
|
|
|
|
add_child(current_child)
|
|
|
|
|
if current_child.has_signal("exit"):
|
|
|
|
|
current_child.connect("exit", _exit)
|
2025-06-21 05:10:55 +00:00
|
|
|
|
elif GlobalConfig.DEBUG:
|
|
|
|
|
print("[特写界面] no exit signal, packed_scene:", packed_scene)
|
2025-05-13 11:45:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _exit(arg = null):
|
|
|
|
|
if current_child:
|
2025-06-28 16:11:21 +00:00
|
|
|
|
if GlobalConfig.DEBUG:
|
|
|
|
|
print("[" + name + "] call lock")
|
2025-06-28 13:42:20 +00:00
|
|
|
|
SceneManager.unlock_player()
|
2025-06-28 16:11:21 +00:00
|
|
|
|
if current_child:
|
|
|
|
|
remove_child(current_child)
|
|
|
|
|
current_child.queue_free()
|
|
|
|
|
current_child = null
|
|
|
|
|
print("quit [", name, "] arg=", arg)
|
2025-05-13 11:45:33 +00:00
|
|
|
|
exit.emit(arg)
|
2025-06-13 08:03:19 +00:00
|
|
|
|
# 退出时,恢复 sign_mark 的输入
|
|
|
|
|
sign_mark.pass_unhandled_input = false
|
2025-05-13 11:45:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
|
|
|
if not current_child:
|
|
|
|
|
return
|
2025-06-21 08:22:31 +00:00
|
|
|
|
if (
|
2025-06-24 17:52:30 +00:00
|
|
|
|
quit_closeup_on_escape
|
2025-06-21 08:22:31 +00:00
|
|
|
|
and (event.is_action_pressed("cancel") or event.is_action_pressed("escape"))
|
|
|
|
|
):
|
2025-05-13 11:45:33 +00:00
|
|
|
|
_exit()
|
2025-06-21 08:22:31 +00:00
|
|
|
|
get_viewport().set_input_as_handled()
|
|
|
|
|
# 在有特写界面时,阻塞 interact 输入
|
|
|
|
|
elif event.is_action_pressed("interact"):
|
|
|
|
|
get_viewport().set_input_as_handled()
|
2025-07-04 13:02:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
###### TOOL BUTTON
|
|
|
|
|
|
|
|
|
|
var scene_root_dir
|
|
|
|
|
var script_template = preload("uid://dnrql1t0j6v8i") as Script
|
|
|
|
|
var scene_template = preload("uid://beifpduqgoyvo") as PackedScene
|
|
|
|
|
var script_root_dir = "res://scene/ground/script/"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _create_scene_with_script():
|
|
|
|
|
if packed_scene:
|
|
|
|
|
print_rich("[color=orange][Closeup2D] packed_scene already exists, skip creating new scene and script.")
|
|
|
|
|
return
|
|
|
|
|
var script = script_template.duplicate(true) as Script
|
|
|
|
|
var new_packed_scene = PackedScene.new()
|
|
|
|
|
var ground = get_node("..")
|
|
|
|
|
while ground and not ground is Ground2D:
|
|
|
|
|
ground = ground.get_node("..")
|
|
|
|
|
if not ground:
|
|
|
|
|
printerr("[Closeup2D] _create_script Ground2D not found.")
|
|
|
|
|
return
|
|
|
|
|
var chapter = ground.scene_name.substr(0, 3)
|
|
|
|
|
var section = ground.scene_name.substr(4, 3)
|
|
|
|
|
if len(chapter) != 3 or len(section) != 3:
|
|
|
|
|
printerr("[Closeup2D] ground scene_name error: %s" % ground.scene_name)
|
|
|
|
|
return
|
|
|
|
|
var base_file_name = script_root_dir + chapter + "/" + section + "_" + name.to_snake_case()
|
|
|
|
|
script.resource_path = base_file_name + ".gd"
|
|
|
|
|
new_packed_scene.resource_path = base_file_name + ".tscn"
|
|
|
|
|
ResourceSaver.save(script, script.resource_path)
|
|
|
|
|
var scene_node = scene_template.instantiate()
|
|
|
|
|
scene_node.set_script(script)
|
|
|
|
|
scene_node.name = name
|
|
|
|
|
new_packed_scene.pack(scene_node)
|
|
|
|
|
ResourceSaver.save(new_packed_scene)
|
|
|
|
|
packed_scene = load(new_packed_scene.resource_path)
|
|
|
|
|
print(
|
|
|
|
|
(
|
|
|
|
|
"[Closeup2D] Script and scene created: %s, %s"
|
|
|
|
|
% [script.resource_path, new_packed_scene.resource_path]
|
|
|
|
|
)
|
|
|
|
|
)
|