xiandie/scene/entity/closeup.gd

111 lines
3.2 KiB
GDScript3
Raw Normal View History

@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
var current_child: Node
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-14 20:43:55 +00:00
# 可以直接调用
func display() -> void:
if current_child:
return
if packed_scene:
if GlobalConfig.DEBUG:
print("[" + name + "] call lock")
SceneManager.lock_player(0, action_key)
# 展示时,禁用 sign_mark 的输入
sign_mark.pass_unhandled_input = true
current_child = packed_scene.instantiate()
add_child(current_child)
if current_child.has_signal("exit"):
current_child.connect("exit", _exit)
elif GlobalConfig.DEBUG:
print("[特写界面] no exit signal, packed_scene:", packed_scene)
func _exit(arg = null):
if current_child:
if GlobalConfig.DEBUG:
print("[" + name + "] call lock")
SceneManager.unlock_player()
if current_child:
remove_child(current_child)
current_child.queue_free()
current_child = null
print("quit [", name, "] arg=", arg)
exit.emit(arg)
# 退出时,恢复 sign_mark 的输入
sign_mark.pass_unhandled_input = false
func _unhandled_input(event: InputEvent) -> void:
if not current_child:
return
if (
2025-06-24 17:52:30 +00:00
quit_closeup_on_escape
and (event.is_action_pressed("cancel") or event.is_action_pressed("escape"))
):
_exit()
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]
)
)