Skip to content
Back to skills

Godot Ecs Component

ASecurity

Godot 4 ECS实体组件系统模式,包含组件化设计、数据与逻辑分离、组件通信。

  • 103 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 12, 2026
developmentgonode

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add 925236118/AlphaAgent --skill godot-ecs-component --agent claude-code

Installs 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 with every re-scan.

Security grade badge for Godot Ecs Component
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/925236118-godot-ecs-component/badge)](https://www.skillsdirectory.com/skills/925236118-godot-ecs-component)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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 提供统一接口访问组件 |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.