Skip to content

EntityModule 实体系统

EntityModule 统一管理实体 Prefab 的异步加载、对象池、生命周期和版本化句柄。业务通过资源 Address Spawn,通过 EntityHandle 写入出生数据、等待 Ready、查询 Agent 和回收实体,不直接 Instantiate、Destroy 或操作内部对象池。

子功能

快速使用

Prefab 根节点挂 Entity,并在同一个 GameObject 上添加所需的 AgentBase 组件。Spawn:

csharp
EntityHandle handle = UtilFunc.SpawnEntity("Go_Enemy")
    .SetData("Level", 5)
    .SetData("SpawnPoint", spawnPoint)
    .WhenReady(entity =>
    {
        if (entity.TryGetAgent(out EnemyAgent enemy))
            enemy.SetTarget(playerHandle);
    });

Spawn 立即返回有效的 Pending 句柄,资源加载和生命周期随后由 Module 推进。

csharp
if (handle.IsValid)
{
    int level = handle.GetData("Level", 1);
    handle.SetData("Difficulty", difficulty);
}

if (handle.IsReady && handle.TryGetAgent(out EnemyAgent enemy))
{
    // 只有 Ready 后才能访问 Agent。
}

handle.Despawn();

IsValid 包含 Loading、Pending 和 Ready;IsReady 表示已经完成 Create -> Spawn -> Enable。Pending 阶段可以读写 Blackboard、注册 WhenReady 或取消 Spawn,但不能访问 Agent。

设计思路

版本化句柄把业务引用与池内 GameObject 解耦,回收后旧引用自然失效。出生 Blackboard 在异步资源尚未 Ready 时已经可写,使调用方不需要额外保存 Pending 参数对象。

Agent 作为 Unity 组件承载需要 Transform/组件引用的功能;CompositePart 作为 SerializeReference 数据对象提供更细粒度的组合;FSM 只处理单实体状态。三者共享统一生命周期和局部上下文,但没有新增全局管理层。

预加载只准备 Prefab 和空池,不盲目实例化对象;具体池容量由真实 Spawn 峰值形成。Release 则作为完整异步屏障,确保玩法 Package 不会在实体仍持有资源时被停用。

注意事项

  • Entity 与 Agent 必须位于 Prefab 同一个 GameObject;Entity 缓存该节点上的 Agent。
  • Pending 句柄能写数据但不能访问 Agent。
  • 每轮复用状态放 Spawn/Despawn,永久结构放 Create/Destroy。
  • Update 和事件注册放 Enable,释放放 Disable。
  • 不要在业务中 Instantiate、Destroy 或手工回池 Entity GameObject。
  • Part 依赖保证结构,不保证执行先后;顺序由 Priority 决定。
  • 运行时新增 Agent/Part 会同步到宿主当前生命周期,但不会重演原时间点的历史业务副作用;新增逻辑必须能够在当前状态安全执行。
  • 释放按需 Package 前,必须等待其中所有 Entity Address 的 Release 成功。

SuperCore 使用 MIT License 开源