在Godot.Net中实现轻量级ECS Entity管理系统
ECS 核心逻辑是把「节点树逻辑」和「游戏数据逻辑」解耦,方便统一管理大批单位(比如怪物、道具、Buff等),并实现:
数据驱动行为(不用每个东西都挂脚本)
集中化管理(例如统一 Tick 所有实体)
易于扩展与复用(如技能系统、状态系统)
1. 定义 Entity 结构
public class Entity
{
public int Id { get; }
private Dictionary<Type, object> _components = new();
public Entity(int id) => Id = id;
public void AddComponent<T>(T component) where T : class
{
_components[typeof(T)] = component;
}
public T GetComponent<T>() where T : class
{
_components.TryGetValue(typeof(T), out var comp);
return comp as T;
}
public bool HasComponent<T>() => _components.ContainsKey(typeof(T));
}
2. 创建 EntityManager
public class EntityManager
{
private int _nextId = 1;
private Dictionary<int, Entity> _entities = new();
public Entity CreateEntity()
{
var entity = new Entity(_nextId++);
_entities[entity.Id] = entity;
return entity;
}
public IEnumerable<Entity> GetAllEntities() => _entities.Values;
}
3. 定义组件(Component)
public class PositionComponent
{
public Vector3 Position;
}
public class HealthComponent
{
public int HP;
public int MaxHP;
}
4. 系统(System)示例
public class HealthSystem
{
public void Update(IEnumerable<Entity> entities)
{
foreach (var e in entities)
{
var health = e.GetComponent<HealthComponent>();
if (health != null && health.HP <= 0)
{
GD.Print($"Entity {e.Id} died.");
}
}
}
}
5. 使用方法
public partial class GameController : Node
{
private EntityManager _entityManager = new();
private HealthSystem _healthSystem = new();
public override void _Ready()
{
var player = _entityManager.CreateEntity();
player.AddComponent(new PositionComponent { Position = new Vector3(0, 0, 0) });
player.AddComponent(new HealthComponent { HP = 100, MaxHP = 100 });
GD.Print("Player entity created.");
}
public override void _Process(double delta)
{
_healthSystem.Update(_entityManager.GetAllEntities());
}
}