@tool class_name Npc2D extends AnimatedSprite2D signal interacted @export var height := 60.0: set(val): height = val if is_node_ready(): speaking_sign.position.y = -height @onready var speaking_animation = %SpeakingAnimationPlayer @onready var speaking_sign = %SpeakingSign2D as Node2D @onready var sign_mark = %Sign as Sign @onready var area2d = %Area2D as Area2D var dialogue_title := "" var dialogue_res = preload("res://asset/dialogue/npc.dialogue") func _ready() -> void: if Engine.is_editor_hint(): speaking_sign.visible = true return speaking_sign.visible = false speaking_sign.position.y = -height if animation: play() sign_mark.interacted.connect(_on_interacted) sign_mark.cancel.connect(_stop) sign_mark.toggle_active.connect(_on_toggle_active) sign_mark.enabled = visible visibility_changed.connect(_on_visibility_changed) func _on_visibility_changed() -> void: sign_mark.enabled = visible func _on_toggle_active(activated: bool) -> void: if activated: _speaking() else: _stop() func _on_interacted() -> void: # %Sfx.play() # _speaking() # play dialogue if dialogue_title: interacted.emit() # # 适配匿名效果 # if anonymous and not dialogue_title.ends_with(anonymous_title_suffix): # dialogue_title += anonymous_title_suffix # elif not anonymous and dialogue_title.ends_with(anonymous_title_suffix): # dialogue_title = dialogue_title.substr( # 0, dialogue_title.length() - anonymous_title_suffix.length() # ) DialogueManager.show_dialogue_balloon(dialogue_res, dialogue_title) SceneManager.freeze_player(0) DialogueManager.dialogue_ended.connect(_dialog_end, CONNECT_ONE_SHOT) func _dialog_end(_res): SceneManager.release_player() func _speaking() -> void: speaking_animation.play("speaking") func _stop() -> void: speaking_animation.play("RESET") func _get(property: StringName) -> Variant: if property == "dialogue_title": return dialogue_title return null func _set(property: StringName, value: Variant) -> bool: if property == "dialogue_title": dialogue_title = value return true return false func _get_property_list() -> Array[Dictionary]: var hint_str = "" if Engine.is_editor_hint(): hint_str = ",".join(dialogue_res.get_ordered_titles()) return [ { "name": "dialogue_title", "type": TYPE_STRING, "hint": PROPERTY_HINT_ENUM_SUGGESTION, "hint_string": hint_str } ]