with one click
godot-ecs-component
Godot 4 ECS实体组件系统模式,包含组件化设计、数据与逻辑分离、组件通信。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Godot 4 ECS实体组件系统模式,包含组件化设计、数据与逻辑分离、组件通信。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Godot 4.x .tscn 场景文件纯文本格式规范与 AI 操作指南 — 文件结构、资源引用、 Transform 变换、属性值格式、信号连接,以及 AI 直接读写 .tscn 文件的操作方法。
Godot 4.x .tscn 场景文件纯文本格式规范与 AI 操作指南 — 文件结构、资源引用、 Transform 变换、属性值格式、信号连接,以及 AI 直接读写 .tscn 文件的操作方法。
Godot 4 Autoload单例模式最佳实践,包含全局管理、事件总线、信号通信。
Godot 4 Buff系统完整实现,支持状态效果管理、持续时间、循环效果、层叠机制等。使用Resource+Component架构。
Godot 4 建造系统实现,包含GridMap方块管理、第一人称视角、射线交互。
Godot 4 种植系统设计,包含植物数据结构、生长阶段、浇水机制、TileMap应用。
| name | godot-ecs-component |
| description | Godot 4 ECS实体组件系统模式,包含组件化设计、数据与逻辑分离、组件通信。 |
ECS(Entity Component System)是一种面向数据的架构模式,将游戏对象拆分为 Entity(实体)、Component(组件)和 System(系统)三个部分。在 Godot 中,我们通过组合 Node 和 Resource 实现 ECS 模式。
┌─────────────────────────────────────────┐
│ Entity (Node) │
│ - 角色节点、敌人节点、可交互对象 │
├─────────────────────────────────────────┤
│ Component (Node) │
│ - HealthComponent、BuffComponent │
│ - 可挂载到任意 Entity 上 │
├─────────────────────────────────────────┤
│ Data (Resource) │
│ - HealthData、WeaponData │
│ - 可序列化、便于保存和复用 │
└─────────────────────────────────────────┘
# health_component.gd
class_name HealthComponent
extends Node
signal health_changed(current: int, maximum: int)
signal damaged(amount: int, source: Node)
signal healed(amount: int)
signal died
@export var max_health: int = 100
@export var invincibility_time: float = 0.0
var current_health: int:
set(value):
var old := current_health
current_health = clampi(value, 0, max_health)
if current_health != old:
health_changed.emit(current_health, max_health)
var _invincible: bool = false
func _ready() -> void:
current_health = max_health
func take_damage(amount: int, source: Node = null) -> int:
if _invincible or current_health <= 0:
return 0
var actual := mini(amount, current_health)
current_health -= actual
damaged.emit(actual, source)
if current_health <= 0:
died.emit()
elif invincibility_time > 0:
_start_invincibility()
return actual
func heal(amount: int) -> int:
var actual := mini(amount, max_health - current_health)
current_health += actual
if actual > 0:
healed.emit(actual)
return actual
func _start_invincibility() -> void:
_invincible = true
await get_tree().create_timer(invincibility_time).timeout
_invincible = false
# hitbox_component.gd
class_name HitboxComponent
extends Area2D
signal hit(hurtbox: HurtboxComponent)
@export var damage: int = 10
@export var knockback_force: float = 200.0
var owner_node: Node
func _ready() -> void:
owner_node = get_parent()
area_entered.connect(_on_area_entered)
func _on_area_entered(area: Area2D) -> void:
if area is HurtboxComponent:
var hurtbox := area as HurtboxComponent
if hurtbox.owner_node != owner_node:
hit.emit(hurtbox)
hurtbox.receive_hit(self)
# hurtbox_component.gd
class_name HurtboxComponent
extends Area2D
signal hurt(hitbox: HitboxComponent)
@export var health_component: HealthComponent
var owner_node: Node
func _ready() -> void:
owner_node = get_parent()
func receive_hit(hitbox: HitboxComponent) -> void:
hurt.emit(hitbox)
if health_component:
health_component.take_damage(hitbox.damage, hitbox.owner_node)
Player (CharacterBody2D)
├── HealthComponent
│ └── (接收伤害,管理生命值)
├── HitboxComponent
│ └── (检测攻击,发送伤害)
├── HurtboxComponent
│ └── (接收伤害,触发健康组件)
├── BuffComponent
│ └── (管理增益/减益效果)
└── InventoryComponent
└── (管理物品栏)
| 原则 | 说明 |
|---|---|
| 单一职责 | 每个组件只负责一个功能 |
| 松耦合 | 组件通过信号通信,不直接依赖 |
| 可复用 | 同一组件可挂载到不同实体 |
| 数据分离 | 数据存储在 Resource 中 |
# weapon_data.gd
class_name WeaponData
extends Resource
@export var name: StringName
@export var damage: int
@export var attack_speed: float
@export var range: float
@export_multiline var description: String
@export var icon: Texture2D
@export var projectile_scene: PackedScene
@export var sound_attack: AudioStream
# character_stats.gd
class_name CharacterStats
extends Resource
signal stat_changed(stat_name: StringName, new_value: float)
@export var max_health: float = 100.0
@export var attack: float = 10.0
@export var defense: float = 5.0
@export var speed: float = 200.0
var _current_health: float
func _init() -> void:
_current_health = max_health
func get_current_health() -> float:
return _current_health
func take_damage(amount: float) -> float:
var actual_damage := maxf(amount - defense, 1.0)
_current_health = maxf(_current_health - actual_damage, 0.0)
stat_changed.emit("health", _current_health)
return actual_damage
func duplicate_for_runtime() -> CharacterStats:
var copy := duplicate() as CharacterStats
copy._current_health = copy.max_health
return copy
| 模式 | 应用场景 |
|---|---|
| 组合模式 | Entity 通过组合组件构建 |
| 观察者模式 | 组件通过信号解耦通信 |
| 资源模式 | 数据存储在 Resource 中便于序列化 |
| 外观模式 | Entity 提供统一接口访问组件 |