新增 Prefab 系统:实体子树存取 + 编辑器 Save As Prefab/拖入实例化 + 脚本 Instantiate

This commit is contained in:
2026-10-08 22:01:26 +08:00
parent b89f431896
commit ed7cb417bd
8 changed files with 643 additions and 208 deletions
+10
View File
@@ -123,6 +123,16 @@ namespace Engine {
//(遍历安全);调用方持有的句柄此后悬空
void Destroy(ECS::Entity e);
// ---- Prefab 实例化(Unity Object.Instantiate 同位)----
// .prefab 文件 → 整棵子树追加进场景(UUID 全量再生,子树内
// Joint.target 自动重映射)。pos/rot = 根实体 local 位姿
//(根挂场景根时即世界位姿)。失败返回 entt::null;
// RigidBody/ScriptComponent 由 PhysicsWorld/ScriptRuntime
// 下一帧对账消化(与 Spawn 同语义)
ECS::Entity Instantiate(const std::string& prefabPath,
const glm::vec3& pos,
const glm::quat& rot = glm::quat{});
// ---- 组件启停(Unity SetActive / Behaviour.enabled 语义)----
// 自身组件总开关(整个脚本组件停 tick,实例保留)
void SetActive(bool on) {
@@ -23,6 +23,8 @@
#ifndef HELLOVULKAN_SCENESERIALIZER_H
#define HELLOVULKAN_SCENESERIALIZER_H
#include <Engine/ECS/Scene.h> // Entity + glm vec3/quat(Prefab API 签名用)
#include <string>
namespace Engine::ECS { class Scene; }
@@ -66,6 +68,31 @@ namespace Engine::Serialization {
static bool DeserializeFromString(ECS::Scene& scene,
Assets::AssetManager& assets,
const std::string& yamlText);
// ---- Prefab(实体子树存取;与场景共用实体段读写,实现见 .cpp)----
// 保存 root 子树(根 + 全部后代,DFS 序:父先于子)到 outPath。
// 格式 = 场景实体段子集:"Prefab:" 文档头 + Version + Entities
// 列表(组件段与场景逐键一致)。首实体 = 根(实例化约定)。
// 失败(根无效/无法写文件)返回 false
static bool SerializePrefab(const ECS::Scene& scene,
Assets::AssetManager& assets,
ECS::Entity root,
const std::string& outPath);
// 实例化 Prefab 到 scene(追加式,不换血)。UUID 全量再生——
// 同一 prefab 多次实例化、与场景既有实体均不冲突;子树内
// Joint.target 按旧→新重映射,指向子树外的引用保持原值。
// overridePos/overrideRot 非空时覆写根实体 local 位姿(根挂
// 场景根时即世界位姿);空指针 = 保留 prefab 授权位姿。
// 返回根实体(= 文件首实体);失败(解析失败/无实体)返回
// entt::null——逐实体容错与场景加载同语义,失败前可能已部分
// 实例化(单实体损坏只跳过该项)
static ECS::Entity InstantiatePrefab(
ECS::Scene& scene, Assets::AssetManager& assets,
const std::string& inPath,
const glm::vec3* overridePos = nullptr,
const glm::quat* overrideRot = nullptr);
};
} // namespace Engine::Serialization