<< All versions
Skill v1.0.0
currentAutomated scan100/100925236118/alphaagent/godot-interactive-system
──Details
PublishedOctober 14, 2026 at 08:17 PM
Content Hashsha256:9c5e75b2575394b6...
Git SHAed0da309bf4d
──Files
Files (1 file, 6.0 KB)
SKILL.md6.0 KBactive
SKILL.md · 239 lines · 6.0 KB
version: "1.0.0" name: godot-interactive-system description: Godot 4 可交互组件设计,包含InteractiveComponent代理组件、NPC对话、区域触发。
Godot 可交互组件设计
概述
可交互组件系统用于实现玩家与游戏世界中各种对象的交互,如 NPC 对话、场景切换、商店等。系统采用代理模式,通过 InteractiveComponent 统一管理交互检测和事件分发。
1. 架构设计
1.1 整体架构
玩家角色 (CharacterBase)│├── Talk Area2D (collision_mask = 256) ← 交互检测区域│ ││ └── Area Entered/Exited Signals│└── try_interact() ← 按 "talk" 键触发│├── talk_target.player_interact() [NPC对话]│└── interactable_area.interact() [关卡出口/商店]
1.2 可交互对象类型
| 类型 | 实现方式 | 触发方式 | |
|---|---|---|---|
| NPC 对话 | npc_base.gd | 按键触发 | |
| 关卡出口 | interactable_level_exit.gd | 按键触发 | |
| 商店 | 自定义 player_interact | 按键触发 | |
| 门 | 自动检测 | 区域进入自动触发 |
2. 交互检测机制
2.1 玩家端配置
gdscript
@onready var talk: Area2D = $Body/talkvar talk_target = nullvar interactable_area = null
Talk Area 配置:
collision_layer = 0 # 不作为碰撞层collision_mask = 256 # 检测位于256层的交互对象monitorable = false # 不被其他 Area 检测
2.2 进入/离开交互区域
gdscript
func _on_talk_area_entered(area: Area2D) -> void:if not area is InteractiveComponent:returnif talk_target:talk_target.exit_interact(self)talk_target = nullif area.has_method("enter_interact"):talk_target = areatalk_target.enter_interact(self)func _on_talk_area_exited(area: Area2D) -> void:if talk_target == area:talk_target.exit_interact(self)talk_target = null
2.3 交互触发
gdscript
func try_interact():if (not talk.has_overlapping_areas() or not talk_target) and not interactable_area:returnif talk_target and talk_target.has_method("player_interact"):talk_target.player_interact(self)returnif interactable_area:interactable_area.interact(self)return
3. InteractiveComponent 代理组件
3.1 核心实现
gdscript
class_name InteractiveComponentextends Area2D@export var agent: Node2D = nullfunc player_interact(player: CharacterBase):if not agent:returnagent.player_interact(player)func enter_interact(player: CharacterBase):if not agent:returnagent.enter_interact(player)func exit_interact(player: CharacterBase):if not agent:returnagent.exit_interact(player)
场景配置:
collision_layer = 256collision_mask = 0monitoring = false
3.2 代理模式优势
玩家交互请求↓InteractiveComponent.player_interact()↓agent.player_interact()
InteractiveComponent可复用于不同对象- 业务逻辑放在
agent中,便于维护 - 可以动态切换
agent改变交互行为
4. 常见交互类型
4.1 NPC 对话交互
gdscript
class_name NPCBaseextends CharacterBody2D@export var interactable: bool = truesignal dialogue_startedfunc _physics_process(delta: float) -> void:if interactable:if can_talk_to_npc():if Input.is_action_just_pressed("talk"):if !interact_lock:dialogue_in_progress = truedialogue_started.emit()
4.2 关卡出口交互
普通出口 - 进入即触发:
gdscript
class_name LevelExitextends Area2Dfunc _on_body_entered(body: Node2D):if body is CharacterBase:body.position = Vector2(-10000, -10000)body.hide()LevelManager.call_deferred("change_scene",LevelManager.ChangeSceneParam.new(target_scene_path, target_scene_entry_tag))
可交互出口 - 需按键触发:
gdscript
class_name InteractableLevelExitextends LevelExitfunc interact(body):body.position = Vector2(-10000, -10000)body.hide()LevelManager.call_deferred("change_scene",LevelManager.ChangeSceneParam.new(target_scene_path, target_scene_entry_tag))
4.3 商店交互
gdscript
func player_interact(player: CharacterBase):var game_operation = handle_game_operation.bind(player)GameDirector.wait_game.connect(game_operation)GameDirector.load_chapter("res://chapters/store_test.json")await GameDirector.finishedGameDirector.wait_game.disconnect(game_operation)func enter_interact(player: CharacterBase):var interact_material := ShaderMaterial.new()interact_material.shader = load("res://resource/shaders/border.gdshader")interact_material.set_shader_parameter("outline_color", Color(1, 1, 1, 1))sprite_2d.material = interact_materialfunc exit_interact(_player: CharacterBase):sprite_2d.material = null
4.4 门交互(自动触发)
gdscript
enum DoorState { CLOSED, OPEN_LEFT, OPEN_RIGHT }func _on_left_in_body_entered(body: Node2D) -> void:if door_state == DoorState.CLOSED:door_state = DoorState.OPEN_RIGHTanimated_sprite_2d.play("open_right")
5. 交互对象场景配置
可交互对象│├── InteractiveComponent (collision_layer = 256)│ ││ └── agent: Node2D ← 实际处理逻辑的节点│├── NPC (npc_base.gd)│├── InteractableLevelExit (interactable_level_exit.gd)│└── Store (自定义 player_interact)
6. 设计模式总结
| 模式 | 应用场景 | |
|---|---|---|
| 代理模式 | InteractiveComponent 转发交互请求给 agent | |
| 观察者模式 | talk_target 跟踪当前交互目标 | |
| 状态机 | NPC 行为状态管理 | |
| 导演模式 | GameDirector 统一管理游戏流程 |