// // PrefabTest.cpp:阶段2 验收脚本——脚本侧 Instantiate(prefab) 运行时 // 实例化链路。 // // PrefabTest(挂任意空实体,作为实例化锚点): // OnStart 按参数路径实例化一次 prefab;Interval > 0 时周期性再实例化 // (多实例验收:每次 UUID 全量再生、物理体独立、沿 X 向排开下落)。 // // 覆盖的引擎设施: // - ScriptBehavior::Instantiate(path, pos, rot)(Unity Object. // Instantiate 同位)→ SceneSerializer::InstantiatePrefab // - prefab 子树含 RigidBody/ScriptComponent 时由 PhysicsWorld/ // ScriptRuntime 下一帧对账消化(与 Spawn 同语义) // // 验收步骤: // 1. 编辑器搭一个实体子树(如 Dynamic 盒刚体 + MeshRenderer 的箱子, // 可再挂个子实体验证层级一起走)→ Outliner 右键 Save As Prefab // (落盘 assets/prefabs/<名字>.prefab) // 2. 建空实体挂 PrefabTest,参数 PrefabPath 填该路径 → Play: // 锚点处出现实例;Interval 设 1.0 可看连续多实例物理下落互不串扰 // 3. 编辑态也可从 Content Browser 把 .prefab 拖进 Outliner(节点= // 挂其下,空白区=挂根)或双击直接实例化——UUID 独立、资产引用有效 // #include #include using namespace Engine; // f32 / ScriptBehavior 等免前缀(对齐 TestShoot) namespace { using Engine::Scripting::ParamBuilder; class PrefabTest final : public Engine::Scripting::ScriptBehavior { public: const char* Name() const override { return "PrefabTest"; } void DeclareParams(ParamBuilder& pb) override { // prefab 资产路径(工作目录相对,同场景/资产管理约定) pb.Field("PrefabPath", &m_PrefabPath, std::string{"assets/prefabs/crate.prefab"}); // 周期实例化间隔(秒;<=0 = 仅 OnStart 实例化一次) pb.Field("Interval", &m_Interval, 0.0f); // 相邻实例的 X 向排开间距(多实例不叠在一起) pb.Field("SpreadX", &m_SpreadX, 2.0f); } void OnStart() override { m_Timer = m_Interval; SpawnInstance(); } void OnUpdate(f32 dt) override { if (m_Interval <= 0.0f) { return; } m_Timer -= dt; if (m_Timer <= 0.0f) { m_Timer = m_Interval; SpawnInstance(); } } private: void SpawnInstance() { // 锚点实体位姿 + 排开偏移;旋转 = 锚点自身旋转 const auto& tr = Transform(); const glm::vec3 pos = tr.GetPosition() + glm::vec3{m_SpreadX * f32(m_Count), 0.0f, 0.0f}; const glm::quat rot = tr.GetRotationQuat(); if (Instantiate(m_PrefabPath, pos, rot) == entt::null) { return; // 路径无效/解析失败:日志已在序列化器里打过 } ++m_Count; } std::string m_PrefabPath; f32 m_Interval = 0.0f; f32 m_SpreadX = 2.0f; f32 m_Timer = 0.0f; int m_Count = 0; // 已实例化份数(排开偏移基准) }; ENGINE_REGISTER_SCRIPT(PrefabTest) } // namespace