本文へ移動
cccskills
無料GitHub で公開

godot-ecs-component

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

インストール方法を見る

含まれるファイル(1)

  • SKILL.md5.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

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 核心组件示例

# 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

# 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

# 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. 数据资源模式

# 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

6. 设计模式总结

模式应用场景
组合模式Entity 通过组合组件构建
观察者模式组件通过信号解耦通信
资源模式数据存储在 Resource 中便于序列化
外观模式Entity 提供统一接口访问组件

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Godot 4 Autoload单例模式最佳实践,包含全局管理、事件总线、信号通信。

日本語の概要は準備中です。原文の説明を表示しています。

925236118/AlphaAgent1032026年10月8日 更新

Godot 4 Buff系统完整实现,支持状态效果管理、持续时间、循环效果、层叠机制等。使用Resource+Component架构。

日本語の概要は準備中です。原文の説明を表示しています。

925236118/AlphaAgent1032026年10月8日 更新

Godot 4 建造系统实现,包含GridMap方块管理、第一人称视角、射线交互。

日本語の概要は準備中です。原文の説明を表示しています。

925236118/AlphaAgent1032026年10月8日 更新

Godot 4 种植系统设计,包含植物数据结构、生长阶段、浇水机制、TileMap应用。

日本語の概要は準備中です。原文の説明を表示しています。

925236118/AlphaAgent1032026年10月8日 更新

Master Godot 4 GDScript patterns including signals, scenes, state machines, and optimization. Use when building Godot games, implementing game systems, or learning GDScript best practices.

日本語の概要は準備中です。原文の説明を表示しています。

925236118/AlphaAgent1032026年10月8日 更新

Godot 4 可交互组件设计,包含InteractiveComponent代理组件、NPC对话、区域触发。

日本語の概要は準備中です。原文の説明を表示しています。

925236118/AlphaAgent1032026年10月8日 更新

925236118 のスキルをすべて見る

このスキルの問題を報告する