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:
@@ -218,6 +218,7 @@ namespace Engine::Serialization {
|
||||
}
|
||||
out << YAML::Key << "Path" << YAML::Value << path;
|
||||
out << YAML::EndMap; // Model(flow)
|
||||
out << YAML::Key << "Active" << YAML::Value << mr->active;
|
||||
out << YAML::EndMap; // MeshRenderer
|
||||
}
|
||||
else {
|
||||
@@ -233,6 +234,7 @@ namespace Engine::Serialization {
|
||||
out << YAML::Key << "Playing" << YAML::Value << a->playing;
|
||||
out << YAML::Key << "Loop" << YAML::Value << a->loop;
|
||||
out << YAML::Key << "Speed" << YAML::Value << a->speed;
|
||||
out << YAML::Key << "Active" << YAML::Value << a->active;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
@@ -240,6 +242,7 @@ namespace Engine::Serialization {
|
||||
out << YAML::Key << "Camera" << YAML::Value << YAML::Flow
|
||||
<< YAML::BeginMap;
|
||||
out << YAML::Key << "Primary" << YAML::Value << c->primary;
|
||||
out << YAML::Key << "Active" << YAML::Value << c->active;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
@@ -254,6 +257,7 @@ namespace Engine::Serialization {
|
||||
out << YAML::Key << "Radius" << YAML::Value << l->radius;
|
||||
out << YAML::Key << "CastShadow" << YAML::Value
|
||||
<< l->castShadow;
|
||||
out << YAML::Key << "Active" << YAML::Value << l->active;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
@@ -304,6 +308,7 @@ namespace Engine::Serialization {
|
||||
<< rb->restitution;
|
||||
out << YAML::Key << "IsSensor" << YAML::Value << rb->isSensor;
|
||||
// bodyId/bodyValid/velocity 由 PhysicsWorld 对账重建,不存
|
||||
out << YAML::Key << "Active" << YAML::Value << rb->active;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
@@ -325,6 +330,7 @@ namespace Engine::Serialization {
|
||||
<< jc->enableLimit;
|
||||
out << YAML::Key << "LimitMin" << YAML::Value << jc->limitMin;
|
||||
out << YAML::Key << "LimitMax" << YAML::Value << jc->limitMax;
|
||||
out << YAML::Key << "Active" << YAML::Value << jc->active;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
@@ -340,6 +346,7 @@ namespace Engine::Serialization {
|
||||
<< cc->maxSlopeAngle;
|
||||
out << YAML::Key << "StepHeight" << YAML::Value
|
||||
<< cc->stepHeight;
|
||||
out << YAML::Key << "Active" << YAML::Value << cc->active;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
@@ -348,6 +355,7 @@ namespace Engine::Serialization {
|
||||
out << YAML::Key << "Script" << YAML::Value << YAML::BeginMap;
|
||||
out << YAML::Key << "ScriptName" << YAML::Value
|
||||
<< sc->scriptName;
|
||||
out << YAML::Key << "Active" << YAML::Value << sc->active;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
@@ -520,6 +528,8 @@ namespace Engine::Serialization {
|
||||
ref.Valid()) {
|
||||
handle.AddComponent<ECS::MeshRendererComponent>(
|
||||
ECS::MeshRendererComponent{ref});
|
||||
handle.GetComponent<ECS::MeshRendererComponent>().active =
|
||||
n["Active"].as<bool>(true); // 缺省 true 向前兼容
|
||||
}
|
||||
else {
|
||||
ENGINE_WARN("SceneSerializer: model unresolved "
|
||||
@@ -536,11 +546,13 @@ namespace Engine::Serialization {
|
||||
a.playing = n["Playing"].as<bool>(a.playing);
|
||||
a.loop = n["Loop"].as<bool>(a.loop);
|
||||
a.speed = n["Speed"].as<f32>(a.speed);
|
||||
a.active = n["Active"].as<bool>(true);
|
||||
}
|
||||
|
||||
if (const YAML::Node n = comps["Camera"]) {
|
||||
auto& c = handle.AddComponent<ECS::CameraComponent>();
|
||||
c.primary = n["Primary"].as<bool>(false);
|
||||
c.active = n["Active"].as<bool>(true);
|
||||
}
|
||||
|
||||
if (const YAML::Node n = comps["Light"]) {
|
||||
@@ -553,6 +565,7 @@ namespace Engine::Serialization {
|
||||
l.color = ReadVec4(n["Color"], l.color);
|
||||
l.radius = n["Radius"].as<f32>(l.radius);
|
||||
l.castShadow = n["CastShadow"].as<bool>(l.castShadow);
|
||||
l.active = n["Active"].as<bool>(true);
|
||||
}
|
||||
|
||||
if (const YAML::Node n = comps["RigidBody"]) {
|
||||
@@ -604,6 +617,7 @@ namespace Engine::Serialization {
|
||||
rb.friction = n["Friction"].as<f32>(rb.friction);
|
||||
rb.restitution = n["Restitution"].as<f32>(rb.restitution);
|
||||
rb.isSensor = n["IsSensor"].as<bool>(rb.isSensor);
|
||||
rb.active = n["Active"].as<bool>(true);
|
||||
// bodyId/bodyValid/velocity 保持默认(对账重建)
|
||||
}
|
||||
|
||||
@@ -623,6 +637,7 @@ namespace Engine::Serialization {
|
||||
jc.enableLimit = n["EnableLimit"].as<bool>(jc.enableLimit);
|
||||
jc.limitMin = n["LimitMin"].as<f32>(jc.limitMin);
|
||||
jc.limitMax = n["LimitMax"].as<f32>(jc.limitMax);
|
||||
jc.active = n["Active"].as<bool>(true);
|
||||
}
|
||||
|
||||
if (const YAML::Node n = comps["CharacterController"]) {
|
||||
@@ -634,6 +649,7 @@ namespace Engine::Serialization {
|
||||
cc.mass = n["Mass"].as<f32>(cc.mass);
|
||||
cc.maxSlopeAngle = n["MaxSlopeAngle"].as<f32>(cc.maxSlopeAngle);
|
||||
cc.stepHeight = n["StepHeight"].as<f32>(cc.stepHeight);
|
||||
cc.active = n["Active"].as<bool>(true);
|
||||
// 状态(速度/着地)由 PhysicsWorld 对账重建,不存
|
||||
}
|
||||
|
||||
@@ -641,6 +657,7 @@ namespace Engine::Serialization {
|
||||
if (const YAML::Node n = comps["Script"]) {
|
||||
auto& sc = handle.AddComponent<ECS::ScriptComponent>();
|
||||
sc.scriptName = n["ScriptName"].as<std::string>("");
|
||||
sc.active = n["Active"].as<bool>(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user