Godot 4 ECS实体组件系统模式,包含组件化设计、数据与逻辑分离、组件通信。
Scanned 9/12/2026
Install to Claude Code
npx -y skills add 925236118/AlphaAgent --skill godot-ecs-component --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Godot Ecs Component?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/925236118-godot-ecs-component)More formats (shields.io, HTML) on the badges page.
---
name: godot-ecs-component
description: Godot 4 ECS实体组件系统模式,包含组件化设计、数据与逻辑分离、组件通信。
---
# Godot ECS 组件系统设计
## 概述
ECS(Entity Component System)是一种面向数据的架构模式,将游戏对象拆分为 Entity(实体)、Component(组件)和 System(系统)三个部分。在 Godot 中,我们通过组合 Node 和 Resource 实现 ECS 模式。
## 1. 架构设计
### 1.1 组件层级结构
```
┌─────────────────────────────────────────┐
│ Entity (Node) │
│ - 角色节点、敌人节点、可交互对象 │
├─────────────────────────────────────────┤
│ Component (Node) │
│ - HealthComponent、BuffComponent │
│ - 可挂载到任意 Entity 上 │
├─────────────────────────────────────────┤
│ Data (Resource) │
│ - HealthData、WeaponData │
│ - 可序列化、便于保存和复用 │
└─────────────────────────────────────────┘
```
### 1.2 核心组件示例
```gdscript
# 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
```
## 2. Hitbox 与 Hurtbox 系统
### 2.1 HitboxComponent
```gdscript
# 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)
```
### 2.2 HurtboxComponent
```gdscript
# 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)
```
## 3. 组件场景结构
```
Player (CharacterBody2D)
├── HealthComponent
│ └── (接收伤害,管理生命值)
├── HitboxComponent
│ └── (检测攻击,发送伤害)
├── HurtboxComponent
│ └── (接收伤害,触发健康组件)
├── BuffComponent
│ └── (管理增益/减益效果)
└── InventoryComponent
└── (管理物品栏)
```
## 4. 组件设计原则
| 原则 | 说明 |
|------|------|
| **单一职责** | 每个组件只负责一个功能 |
| **松耦合** | 组件通过信号通信,不直接依赖 |
| **可复用** | 同一组件可挂载到不同实体 |
| **数据分离** | 数据存储在 Resource 中 |
## 5. 数据资源模式
```gdscript
# 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
```
```gdscript
# 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
```
## 6. 设计模式总结
| 模式 | 应用场景 |
|------|----------|
| **组合模式** | Entity 通过组合组件构建 |
| **观察者模式** | 组件通过信号解耦通信 |
| **资源模式** | 数据存储在 Resource 中便于序列化 |
| **外观模式** | Entity 提供统一接口访问组件 |
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!