feat(ecs): per-component enable/disable + inspector rework
Add `active` flag to the 8 behavior components (Unity enabled / UE SetActive semantics; structural Id/Name/Transform excluded). Consumers skip disabled components: renderer (mesh/light/anim), primary camera election, physics reconciliation (body/constraint/character destroyed and rebuilt on toggle), scripts keep instance but stop ticking. Inspector: component headers now carry an enable checkbox and a remove button, Add-Component menu greys out attached entries, and conflict hints added (RigidBody <-> CharacterController mutual exclusion, Joint requires RigidBody, Animation requires MeshRenderer, unregistered script name). Scenes persist Active per component (default true).
This commit is contained in:
@@ -123,12 +123,14 @@ namespace Engine::ECS {
|
||||
// ECS 不感知资产系统内部;解析归 AssetManager,悬空由 generation 拦截。
|
||||
struct MeshRendererComponent {
|
||||
ModelRef model;
|
||||
bool active = true; // 禁用 = 渲染/拾取跳过(Unity enabled / UE SetActive)
|
||||
};
|
||||
|
||||
// 骨骼动画播放状态(纯数据 + 便捷控制)。
|
||||
// 采样/局部层混合逻辑在 SceneRenderer::BuildFrame(渲染侧唯一消费者);
|
||||
// ImGui 面板经 Play()/字段直接驱动。无此组件 = 按绑定姿势渲染。
|
||||
struct AnimationComponent {
|
||||
bool active = true; // 禁用 = 暂停采样(按当前帧姿态定格)
|
||||
int clipIndex = 0; // 当前 clip(Model::GetClips 下标)
|
||||
bool playing = true;
|
||||
bool loop = true;
|
||||
@@ -158,6 +160,7 @@ namespace Engine::ECS {
|
||||
|
||||
// 相机。一个场景中 primary=true 的实体是当前渲染视角。
|
||||
struct CameraComponent {
|
||||
bool active = true; // 禁用 = 退出 primary 候选
|
||||
Camera camera;
|
||||
bool primary = false;
|
||||
};
|
||||
@@ -166,6 +169,7 @@ namespace Engine::ECS {
|
||||
// Directional——方向即照射方向(无位置,阴影光源用第 0 盏方向光)
|
||||
// Point——位置取实体 Transform(固有的),向四周发光 + 距离衰减
|
||||
struct LightComponent {
|
||||
bool active = true; // 禁用 = 不进光照
|
||||
enum class Type : u8 { Directional = 0, Point = 1 };
|
||||
Type type = Type::Directional;
|
||||
glm::vec3 direction{0.0f, -1.0f, 0.0f}; // 仅方向光
|
||||
@@ -183,6 +187,7 @@ namespace Engine::ECS {
|
||||
// 角色 = CharacterControllerComponent(CharacterVirtual),载具 = VehicleComponent
|
||||
// (VehicleConstraint)——都走 PhysicsWorld 门面,不复用本组件。
|
||||
struct RigidBodyComponent {
|
||||
bool active = true; // 禁用 = body 销毁/不建(对账自然消化)
|
||||
enum class BodyType : u8 { Static = 0, Dynamic = 1, Kinematic = 2 };
|
||||
// Mesh:用实体 MeshRenderer 的视觉网格建碰撞(Unity MeshCollider
|
||||
// 语义)——Static → Jolt MeshShape(精确三角网格,不可移动);
|
||||
@@ -241,6 +246,7 @@ namespace Engine::ECS {
|
||||
// target 存 UUID(跨存档稳定),惰性解析——SyncScene 每帧按 UUID 反查
|
||||
// 实体:序列化无需两遍解析,UUID 再生后自然失联,加载顺序无关
|
||||
struct JointComponent {
|
||||
bool active = true; // 禁用 = 约束销毁/不建(对账自然消化)
|
||||
enum class Type : u8 { Fixed = 0, Hinge = 1, Ball = 2 };
|
||||
Type type = Type::Fixed;
|
||||
UUID target{}; // 目标实体(0 = 未设置,不建约束)
|
||||
@@ -264,6 +270,7 @@ namespace Engine::ECS {
|
||||
// 只存参数(序列化:存参数不存状态),速度/着地等运行时状态在
|
||||
// PhysicsWorld 的 CharacterController 里(对账重建)
|
||||
struct CharacterControllerComponent {
|
||||
bool active = true; // 禁用 = 角色移除(重启用按当前 Transform 重建)
|
||||
f32 radius = 0.3f; // 胶囊半径
|
||||
f32 capsuleHalfHeight = 0.4f; // 圆柱段半高(总高 = 2*(hh+r))
|
||||
f32 mass = 70.0f;
|
||||
@@ -278,6 +285,7 @@ namespace Engine::ECS {
|
||||
// ENGINE_REGISTER_SCRIPT 自注册;将来 Lua/C# 脚本同键解析。
|
||||
// 实例生命周期由 ScriptRuntime 对账管理(不进组件,保持可拷贝)
|
||||
struct ScriptComponent {
|
||||
bool active = true; // 禁用 = 实例保留但停 OnUpdate(Unity disable)
|
||||
std::string scriptName;
|
||||
|
||||
bool operator==(const ScriptComponent&) const = default;
|
||||
|
||||
Reference in New Issue
Block a user