Fixed prefabs and prefab instancing

This commit is contained in:
Antoine Pilote
2023-08-09 00:30:38 -04:00
parent 67b8ca50fd
commit 67577b902b
5 changed files with 53 additions and 39 deletions

View File

@@ -8,7 +8,7 @@ namespace Nuake
Ref<Prefab> prefab = CreateRef<Prefab>();
ParentComponent parentC = entity.GetComponent<ParentComponent>();
prefab->EntityWalker(entity);
prefab->Root = entity;
return prefab;
}

View File

@@ -47,6 +47,7 @@ namespace Nuake {
for (Entity e : Entities)
entities.push_back(e.Serialize());
j["Root"] = Root.GetComponent<NameComponent>().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<NameComponent>();
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<NameComponent>();
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);
}

View File

@@ -31,7 +31,8 @@
#include <chrono>
#include "src/Core/OS.h"
namespace Nuake {
namespace Nuake
{
Ref<Scene> Scene::New()
{
return CreateRef<Scene>();
@@ -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.

View File

@@ -60,6 +60,8 @@ namespace Nuake
Ref<Camera> 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);

View File

@@ -107,11 +107,8 @@ namespace Nuake
return;
}
Entity& newEntity = Engine::GetCurrentScene()->CreateEntity(prefabName);
auto& prefabComponent = newEntity.AddComponent<PrefabComponent>();
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)