Merge pull request #1233 from aws-lumberyard-dev/Prefabs/NestedContainerExport

Fix issue involving missing parent container entities in spawnables
main
sconel 5 years ago committed by GitHub
commit 38b1a89631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -187,13 +187,14 @@ namespace AzToolsFramework
return removedEntity; return removedEntity;
} }
void Instance::DetachNestedEntities(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback) void Instance::DetachAllEntitiesInHierarchy(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback)
{ {
callback(AZStd::move(DetachContainerEntity()));
DetachEntities(callback); DetachEntities(callback);
for (const auto& [instanceAlias, instance] : m_nestedInstances) for (const auto& [instanceAlias, instance] : m_nestedInstances)
{ {
instance->DetachNestedEntities(callback); instance->DetachAllEntitiesInHierarchy(callback);
} }
} }

@ -87,7 +87,15 @@ namespace AzToolsFramework
bool AddEntity(AZ::Entity& entity, EntityAlias entityAlias); bool AddEntity(AZ::Entity& entity, EntityAlias entityAlias);
AZStd::unique_ptr<AZ::Entity> DetachEntity(const AZ::EntityId& entityId); AZStd::unique_ptr<AZ::Entity> DetachEntity(const AZ::EntityId& entityId);
void DetachEntities(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback); void DetachEntities(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback);
void DetachNestedEntities(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback);
/**
* Detaches all entities in the instance hierarchy.
* Includes all direct entities, all nested entities, and all container entities.
* Note that without container entities the hierarchy that remains cannot be used further without restoring new ones.
* @param callback A user provided callback that can be used to capture ownership and manipulate the detached entities.
*/
void DetachAllEntitiesInHierarchy(const AZStd::function<void(AZStd::unique_ptr<AZ::Entity>)>& callback);
void RemoveNestedEntities(const AZStd::function<bool(const AZStd::unique_ptr<AZ::Entity>&)>& filter); void RemoveNestedEntities(const AZStd::function<bool(const AZStd::unique_ptr<AZ::Entity>&)>& filter);
void Reset(); void Reset();

@ -38,11 +38,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
// going to be used to create clones of the entities. // going to be used to create clones of the entities.
{ {
AzFramework::Spawnable::EntityList& entities = spawnable.GetEntities(); AzFramework::Spawnable::EntityList& entities = spawnable.GetEntities();
if (instance.HasContainerEntity()) instance.DetachAllEntitiesInHierarchy(
{
entities.emplace_back(AZStd::move(instance.DetachContainerEntity()));
}
instance.DetachNestedEntities(
[&entities](AZStd::unique_ptr<AZ::Entity> entity) [&entities](AZStd::unique_ptr<AZ::Entity> entity)
{ {
entities.emplace_back(AZStd::move(entity)); entities.emplace_back(AZStd::move(entity));

@ -71,24 +71,29 @@ namespace UnitTest
m_prefabSystemComponent->CreatePrefab({ entitiesCreated[0] }, {}, "test/path1")); m_prefabSystemComponent->CreatePrefab({ entitiesCreated[0] }, {}, "test/path1"));
ASSERT_TRUE(firstInstance); ASSERT_TRUE(firstInstance);
ASSERT_TRUE(firstInstance->HasContainerEntity());
expectedEntityNameSet.insert(firstInstance->GetContainerEntity()->get().GetName());
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> secondInstance( AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> secondInstance(
m_prefabSystemComponent->CreatePrefab({ entitiesCreated[1] }, MakeInstanceList(AZStd::move(firstInstance)), "test/path2")); m_prefabSystemComponent->CreatePrefab({ entitiesCreated[1] }, MakeInstanceList(AZStd::move(firstInstance)), "test/path2"));
ASSERT_TRUE(secondInstance); ASSERT_TRUE(secondInstance);
ASSERT_TRUE(secondInstance->HasContainerEntity());
expectedEntityNameSet.insert(secondInstance->GetContainerEntity()->get().GetName());
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> thirdInstance( AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> thirdInstance(
m_prefabSystemComponent->CreatePrefab({ entitiesCreated[2] }, MakeInstanceList(AZStd::move(secondInstance)), "test/path3")); m_prefabSystemComponent->CreatePrefab({ entitiesCreated[2] }, MakeInstanceList(AZStd::move(secondInstance)), "test/path3"));
ASSERT_TRUE(thirdInstance); ASSERT_TRUE(thirdInstance);
ASSERT_TRUE(thirdInstance->HasContainerEntity()); ASSERT_TRUE(thirdInstance->HasContainerEntity());
auto& containerEntity = thirdInstance->GetContainerEntity()->get(); expectedEntityNameSet.insert(thirdInstance->GetContainerEntity()->get().GetName());
expectedEntityNameSet.insert(containerEntity.GetName());
//Create Spawnable //Create Spawnable
auto& prefabDom = m_prefabSystemComponent->FindTemplateDom(thirdInstance->GetTemplateId()); auto& prefabDom = m_prefabSystemComponent->FindTemplateDom(thirdInstance->GetTemplateId());
AzFramework::Spawnable spawnable; AzFramework::Spawnable spawnable;
AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(spawnable, prefabDom); AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(spawnable, prefabDom);
EXPECT_EQ(spawnable.GetEntities().size() - 1, normalEntityCount); // 1 for container entity EXPECT_EQ(spawnable.GetEntities().size(), normalEntityCount + 3); // +1 for each container entity
const auto& spawnableEntities = spawnable.GetEntities(); const auto& spawnableEntities = spawnable.GetEntities();
AZStd::unordered_set<AZStd::string> actualEntityNameSet; AZStd::unordered_set<AZStd::string> actualEntityNameSet;
@ -97,6 +102,6 @@ namespace UnitTest
actualEntityNameSet.insert(spawnableEntity->GetName()); actualEntityNameSet.insert(spawnableEntity->GetName());
} }
EXPECT_EQ(expectedEntityNameSet, actualEntityNameSet); EXPECT_EQ(actualEntityNameSet, expectedEntityNameSet);
} }
} }

@ -213,7 +213,7 @@ namespace UnitTest
AZStd::unique_ptr<Instance> convertedInstance(aznew Instance()); AZStd::unique_ptr<Instance> convertedInstance(aznew Instance());
ASSERT_TRUE(AzToolsFramework::Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*convertedInstance, m_prefabDom)); ASSERT_TRUE(AzToolsFramework::Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*convertedInstance, m_prefabDom));
convertedInstance->DetachNestedEntities( convertedInstance->DetachAllEntitiesInHierarchy(
[this](AZStd::unique_ptr<AZ::Entity> entity) [this](AZStd::unique_ptr<AZ::Entity> entity)
{ {
m_runtimeEntities.emplace_back(entity.release()); m_runtimeEntities.emplace_back(entity.release());

Loading…
Cancel
Save