diff --git a/Nuake/src/Resource/Prefab.cpp b/Nuake/src/Resource/Prefab.cpp index 22456a1e..4f5ae5bb 100644 --- a/Nuake/src/Resource/Prefab.cpp +++ b/Nuake/src/Resource/Prefab.cpp @@ -8,7 +8,7 @@ namespace Nuake Ref prefab = CreateRef(); ParentComponent parentC = entity.GetComponent(); prefab->EntityWalker(entity); - + prefab->Root = entity; return prefab; } diff --git a/Nuake/src/Resource/Prefab.h b/Nuake/src/Resource/Prefab.h index f6de3fbf..414c1814 100644 --- a/Nuake/src/Resource/Prefab.h +++ b/Nuake/src/Resource/Prefab.h @@ -47,6 +47,7 @@ namespace Nuake { for (Entity e : Entities) entities.push_back(e.Serialize()); + j["Root"] = Root.GetComponent().ID; SERIALIZE_VAL_LBL("Entities", entities); // Manual correction to remove parent if we are prefabing a child. @@ -68,15 +69,27 @@ namespace Nuake { Path = j["Path"]; if (j.contains("Entities")) { - return true; + const auto& scene = Engine::GetCurrentScene(); + for (json e : j["Entities"]) { - Entity entity = Engine::GetCurrentScene()->CreateEntity("-"); - auto& nameComponent = entity.GetComponent(); + Entity entity = { scene->m_Registry.create(), scene.get() }; + entity.Deserialize(e); // Id gets overriden by serialized id. - int entityId = nameComponent.ID; - entity.Deserialize(e); - nameComponent.ID = entityId; + auto& nameComponent = entity.GetComponent(); + bool isRoot = false; + if (nameComponent.ID == j["Root"]) + { + isRoot = true; // We found the root entity of the prefab. + } + + nameComponent.Name = scene->GetUniqueEntityName(nameComponent.Name); + nameComponent.ID = OS::GetTime(); + + if (isRoot) + { + Root = entity; + } this->AddEntity(entity); } diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 41e59297..cad0331e 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -31,7 +31,8 @@ #include #include "src/Core/OS.h" -namespace Nuake { +namespace Nuake +{ Ref Scene::New() { return CreateRef(); @@ -209,6 +210,31 @@ namespace Nuake { return CreateEntity(name, (int)OS::GetTime()); } + std::string Scene::GetUniqueEntityName(const std::string& name) + { + std::string entityName; + if (GetEntity(name) == Entity()) + { + return name; + } + + // Try to generate a unique name + for (uint32_t i = 1; i < 4096; i++) + { + const std::string& entityEnumName = name + std::to_string(i); + const auto& entityId = GetEntity(entityEnumName).GetHandle(); + if (entityId == -1) + { + return entityEnumName; + break; + } + } + + // We ran out of names + Logger::Log("Failed to create unique entity name. Limit reached with name: " + name, "scene", WARNING); + return name; + } + Entity Scene::CreateEntity(const std::string& name, int id) { if (name.empty()) @@ -217,32 +243,8 @@ namespace Nuake { return Entity(); } - std::string entityName; - if (GetEntity(name) == Entity()) - { - entityName = name; - } - else - { - // Try to generate a unique name - for (uint32_t i = 1; i < 4096; i++) - { - const std::string& entityEnumName = name + std::to_string(i); - const auto& entityId = GetEntity(entityEnumName).GetHandle(); - if (entityId == -1) - { - entityName = entityEnumName; - break; - } - } - - if (entityName.empty()) // We ran out of names!!! - { - Logger::Log("Failed to create entity. Limit reached with name: " + name, "scene", CRITICAL); - return Entity(); - } - } - + std::string entityName = GetUniqueEntityName(name); + Entity entity = { m_Registry.create(), this }; // Add all mandatory component. An entity cannot exist without these. diff --git a/Nuake/src/Scene/Scene.h b/Nuake/src/Scene/Scene.h index af317caf..33e03ac2 100644 --- a/Nuake/src/Scene/Scene.h +++ b/Nuake/src/Scene/Scene.h @@ -60,6 +60,8 @@ namespace Nuake Ref GetCurrentCamera(); + std::string GetUniqueEntityName(const std::string& name); + Entity CreateEntity(const std::string& name); Entity CreateEntity(const std::string& name, int id); void DestroyEntity(Entity entity); diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index 40b03e32..0a2ffc7d 100644 --- a/Nuake/src/Scripting/Modules/SceneModule.h +++ b/Nuake/src/Scripting/Modules/SceneModule.h @@ -107,11 +107,8 @@ namespace Nuake return; } - Entity& newEntity = Engine::GetCurrentScene()->CreateEntity(prefabName); - auto& prefabComponent = newEntity.AddComponent(); - prefabComponent.PrefabInstance = Prefab::New(prefabPath); - - wrenSetSlotDouble(vm, 0, newEntity.GetHandle()); + const auto& prefab = Prefab::New(prefabPath); + wrenSetSlotDouble(vm, 0, prefab->Root.GetHandle()); } static void EntityHasComponent(WrenVM* vm)