123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- // this file is essentially a duplicate of PrefabDetachPrefabTests.cpp
- // but it calls the API which deletes the container.
- // This means that SOME, but not necessarily all, of the setup for each test is the same
- // But the actual outcome is very different for each test.
- #include <AzToolsFramework/Entity/EditorEntityHelpers.h>
- #include <Prefab/PrefabTestFixture.h>
- namespace UnitTest
- {
- using PrefabDetachPrefabTests = PrefabTestFixture;
- TEST_F(PrefabDetachPrefabTests, DetachPrefabAndRemoveContainerEntityUnderLevelSucceeds)
- {
- // Level
- // | Car (prefab) <-- detach prefab
- // | Tire
- // | Belt
- // detaching removes the wrapper prefab object, so result is just
- // Level
- // | Tire
- // | Belt
- const AZStd::string carPrefabName = "CarPrefab";
- const AZStd::string tireEntityName = "Tire";
- const AZStd::string beltEntityName = "Belt";
- AZ::IO::Path engineRootPath;
- m_settingsRegistryInterface->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
- AZ::IO::Path carPrefabFilepath = engineRootPath / carPrefabName;
- AZ::EntityId tireEntityId = CreateEditorEntityUnderRoot(tireEntityName);
- CreateEditorEntity(beltEntityName, tireEntityId);
- AZ::EntityId carContainerId = CreateEditorPrefab(carPrefabFilepath, { tireEntityId });
- InstanceAlias carInstanceAlias = FindNestedInstanceAliasInInstance(GetRootContainerEntityId(), carPrefabName);
- // Detach the car prefab.
- PrefabOperationResult result = m_prefabPublicInterface->DetachPrefabAndRemoveContainerEntity(carContainerId);
- ASSERT_TRUE(result.IsSuccess());
- PropagateAllTemplateChanges();
- // Validate there is no nested instance in the level prefab instance.
- ValidateNestedInstanceNotUnderInstance(GetRootContainerEntityId(), carInstanceAlias);
- InstanceOptionalReference levelInstance = m_instanceEntityMapperInterface->FindOwningInstance(GetRootContainerEntityId());
- ASSERT_TRUE(levelInstance.has_value());
- // Validate there are two entities in the level prefab instance (Tire, Belt)
- EXPECT_EQ(levelInstance->get().GetEntityAliasCount(), 2);
- // Validate that the car entity (the prefab wrapper) does not exist.
- AZStd::string carEntityAliasAfterDetach = FindEntityAliasInInstance(GetRootContainerEntityId(), carPrefabName);
- EXPECT_STREQ(carEntityAliasAfterDetach.c_str(), "");
- // Validate that the tire's parent entity is the level container entity.
- AZStd::string tireEntityAliasAfterDetach = FindEntityAliasInInstance(GetRootContainerEntityId(), tireEntityName);
- AZ::EntityId tireEntityIdAfterDetach = levelInstance->get().GetEntityId(tireEntityAliasAfterDetach);
- EXPECT_TRUE(tireEntityIdAfterDetach.IsValid());
- AZ::EntityId parentEntityIdForTire;
- AZ::TransformBus::EventResult(parentEntityIdForTire, tireEntityIdAfterDetach, &AZ::TransformInterface::GetParentId);
- EXPECT_EQ(levelInstance->get().GetContainerEntityId(), parentEntityIdForTire);
- // Validate that the belt's parent entity is the tire.
- AZStd::string beltEntityAliasAfterDetach = FindEntityAliasInInstance(GetRootContainerEntityId(), beltEntityName);
- AZ::EntityId beltEntityIdAfterDetach = levelInstance->get().GetEntityId(beltEntityAliasAfterDetach);
- EXPECT_TRUE(beltEntityIdAfterDetach.IsValid());
- AZ::EntityId parentEntityIdForBelt;
- AZ::TransformBus::EventResult(parentEntityIdForBelt, beltEntityIdAfterDetach, &AZ::TransformInterface::GetParentId);
- EXPECT_EQ(tireEntityIdAfterDetach, parentEntityIdForBelt);
- }
- TEST_F(PrefabDetachPrefabTests, DetachPrefabAndRemoveContainerEntityUnderParentSucceeds)
- {
- // Level
- // | Garage
- // | Car (prefab) <-- detach prefab
- // | Tire
- // expected result
- // Level
- // | Garage
- // | Tire (car is gone)
- const AZStd::string carPrefabName = "CarPrefab";
- const AZStd::string garageEntityName = "Garage";
- const AZStd::string tireEntityName = "Tire";
- AZ::IO::Path engineRootPath;
- m_settingsRegistryInterface->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
- AZ::IO::Path carPrefabFilepath = engineRootPath / carPrefabName;
- AZ::EntityId garageEntityId = CreateEditorEntityUnderRoot(garageEntityName);
- AZ::EntityId tireEntityId = CreateEditorEntity(tireEntityName, garageEntityId);
- AZ::EntityId carContainerId = CreateEditorPrefab(carPrefabFilepath, { tireEntityId });
- InstanceAlias carInstanceAlias = FindNestedInstanceAliasInInstance(GetRootContainerEntityId(), carPrefabName);
- // Detach the car prefab.
- PrefabOperationResult result = m_prefabPublicInterface->DetachPrefabAndRemoveContainerEntity(carContainerId);
- ASSERT_TRUE(result.IsSuccess());
- PropagateAllTemplateChanges();
- // Validate there is no nested instance in the level prefab instance.
- ValidateNestedInstanceNotUnderInstance(GetRootContainerEntityId(), carInstanceAlias);
- InstanceOptionalReference levelInstance = m_instanceEntityMapperInterface->FindOwningInstance(GetRootContainerEntityId());
- ASSERT_TRUE(levelInstance.has_value());
- // Validate there are two entities in the level prefab instance (the car should be gone)
- EXPECT_EQ(levelInstance->get().GetEntityAliasCount(), 2);
- // Validate that the garage's parent entity is the level container entity.
- AZStd::string garageEntityAliasAfterDetach = FindEntityAliasInInstance(GetRootContainerEntityId(), garageEntityName);
- AZ::EntityId garageEntityIdAfterDetach = levelInstance->get().GetEntityId(garageEntityAliasAfterDetach);
- EXPECT_TRUE(garageEntityIdAfterDetach.IsValid());
- AZ::EntityId parentEntityIdForGarage;
- AZ::TransformBus::EventResult(parentEntityIdForGarage, garageEntityIdAfterDetach, &AZ::TransformInterface::GetParentId);
- EXPECT_EQ(levelInstance->get().GetContainerEntityId(), parentEntityIdForGarage);
- // Validate that the car is gone
- AZStd::string carEntityAliasAfterDetach = FindEntityAliasInInstance(GetRootContainerEntityId(), carPrefabName);
- AZ::EntityId carEntityIdAfterDetach = levelInstance->get().GetEntityId(carEntityAliasAfterDetach);
- EXPECT_FALSE(carEntityIdAfterDetach.IsValid());
- // Validate that the tire's parent entity is the garage.
- AZStd::string tireEntityAliasAfterDetach = FindEntityAliasInInstance(GetRootContainerEntityId(), tireEntityName);
- AZ::EntityId tireEntityIdAfterDetach = levelInstance->get().GetEntityId(tireEntityAliasAfterDetach);
- EXPECT_TRUE(tireEntityIdAfterDetach.IsValid());
- AZ::EntityId parentEntityIdForTire;
- AZ::TransformBus::EventResult(parentEntityIdForTire, tireEntityIdAfterDetach, &AZ::TransformInterface::GetParentId);
- EXPECT_EQ(garageEntityIdAfterDetach, parentEntityIdForTire);
- }
- TEST_F(PrefabDetachPrefabTests, DetachPrefabAndRemoveContainerEntityWithNestedPrefabSucceeds)
- {
- // Level
- // | Car (prefab) <-- detach prefab
- // | Wheel (prefab)
- // | Tire
- // expected result
- // Level
- // | Wheel (prefab), car is gone
- // | Tire
- const AZStd::string carPrefabName = "CarPrefab";
- const AZStd::string wheelPrefabName = "WheelPrefab";
- const AZStd::string tireEntityName = "Tire";
- AZ::IO::Path engineRootPath;
- m_settingsRegistryInterface->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
- AZ::IO::Path carPrefabFilepath = engineRootPath / carPrefabName;
- AZ::IO::Path wheelPrefabFilepath = engineRootPath / wheelPrefabName;
- AZ::EntityId tireEntityId = CreateEditorEntityUnderRoot(tireEntityName);
- AZ::EntityId wheelContainerId = CreateEditorPrefab(wheelPrefabFilepath, { tireEntityId });
- EntityAlias tireEntityAlias = FindEntityAliasInInstance(wheelContainerId, tireEntityName);
- AZ::EntityId carContainerId = CreateEditorPrefab(carPrefabFilepath, { wheelContainerId });
- InstanceAlias carInstanceAlias = FindNestedInstanceAliasInInstance(GetRootContainerEntityId(), carPrefabName);
- // Detach the car prefab.
- PrefabOperationResult result = m_prefabPublicInterface->DetachPrefabAndRemoveContainerEntity(carContainerId);
- ASSERT_TRUE(result.IsSuccess());
- PropagateAllTemplateChanges();
- // Validate there is no car instance in the level prefab instance.
- ValidateNestedInstanceNotUnderInstance(GetRootContainerEntityId(), carInstanceAlias);
- // Validate there is wheel instance in the level prefab instance.
- InstanceAlias wheelInstanceAlias = FindNestedInstanceAliasInInstance(GetRootContainerEntityId(), wheelPrefabName);
- ValidateNestedInstanceUnderInstance(GetRootContainerEntityId(), wheelInstanceAlias);
- InstanceOptionalReference levelInstance = m_instanceEntityMapperInterface->FindOwningInstance(GetRootContainerEntityId());
- ASSERT_TRUE(levelInstance.has_value());
-
- AZStd::vector<InstanceOptionalReference> nestedInstances;
- levelInstance->get().GetNestedInstances(
- [&nestedInstances](AZStd::unique_ptr<Instance>& nestedInstance)
- {
- nestedInstances.push_back(*(nestedInstance.get()));
- });
- EXPECT_EQ(nestedInstances.size(), 1) << "There should be only one nested instance in level after detaching.";
- EXPECT_TRUE(nestedInstances[0].has_value());
- // Validate that the car prefab is gone
- AZStd::string carEntityAliasAfterDetach = FindEntityAliasInInstance(GetRootContainerEntityId(), carPrefabName);
- AZ::EntityId carEntityIdAfterDetach = levelInstance->get().GetEntityId(carEntityAliasAfterDetach);
- EXPECT_FALSE(carEntityIdAfterDetach.IsValid());
- // Validate that the wheel's parent entity is the level.
- Instance& wheelInstanceAfterDetach = nestedInstances[0]->get();
- AZ::EntityId wheelContainerIdAfterDetach = wheelInstanceAfterDetach.GetContainerEntityId();
- EXPECT_TRUE(wheelContainerIdAfterDetach.IsValid());
- AZ::EntityId parentEntityIdForWheel;
- AZ::TransformBus::EventResult(parentEntityIdForWheel, wheelContainerIdAfterDetach, &AZ::TransformInterface::GetParentId);
- EXPECT_EQ(levelInstance->get().GetContainerEntityId(), parentEntityIdForWheel);
- // Validate that the tire's parent entity is the wheel.
- tireEntityId = wheelInstanceAfterDetach.GetEntityId(tireEntityAlias);
- EXPECT_TRUE(tireEntityId.IsValid());
- AZ::EntityId parentEntityIdForTire;
- AZ::TransformBus::EventResult(parentEntityIdForTire, tireEntityId, &AZ::TransformInterface::GetParentId);
- EXPECT_EQ(wheelContainerIdAfterDetach, parentEntityIdForTire);
- }
- TEST_F(PrefabDetachPrefabTests, DetachPrefabAndRemoveContainerEntityWithNestedPrefabUnderTopLevelEntitySucceeds)
- {
- // Level
- // | Car (prefab) <-- detach prefab
- // | Wheels <-- top level entity
- // | Wheel (prefab)
- // | Tire
- // result (car is gone)
- // Level
- // | Wheels <-- top level entity
- // | Wheel (prefab)
- // | Tire
- const AZStd::string carPrefabName = "CarPrefab";
- const AZStd::string wheelPrefabName = "WheelPrefab";
- const AZStd::string wheelsEntityName = "Wheels";
- const AZStd::string tireEntityName = "Tire";
- AZ::IO::Path engineRootPath;
- m_settingsRegistryInterface->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
- AZ::IO::Path carPrefabFilepath = engineRootPath / carPrefabName;
- AZ::IO::Path wheelPrefabFilepath = engineRootPath / wheelPrefabName;
- // Create the wheels and tire entities.
- AZ::EntityId wheelsEntityId = CreateEditorEntityUnderRoot(wheelsEntityName);
- AZ::EntityId tireEntityId = CreateEditorEntity(tireEntityName, wheelsEntityId);
- // Create the wheel prefab.
- AZ::EntityId wheelContainerId = CreateEditorPrefab(wheelPrefabFilepath, { tireEntityId });
- EntityAlias tireEntityAlias = FindEntityAliasInInstance(wheelContainerId, tireEntityName);
- // Create the car prefab.
- AZ::EntityId carContainerId = CreateEditorPrefab(carPrefabFilepath, { wheelsEntityId });
- InstanceAlias carInstanceAlias = FindNestedInstanceAliasInInstance(GetRootContainerEntityId(), carPrefabName);
- // Detach the car prefab.
- PrefabOperationResult result = m_prefabPublicInterface->DetachPrefabAndRemoveContainerEntity(carContainerId);
- ASSERT_TRUE(result.IsSuccess());
- PropagateAllTemplateChanges();
- // Validate there is no car instance in the level prefab instance.
- ValidateNestedInstanceNotUnderInstance(GetRootContainerEntityId(), carInstanceAlias);
- // Validate there is wheels entity in the level prefab instance.
- EntityAlias wheelsEntityAlias = FindEntityAliasInInstance(GetRootContainerEntityId(), wheelsEntityName);
- ValidateEntityUnderInstance(GetRootContainerEntityId(), wheelsEntityAlias, wheelsEntityName);
- // Validate there is wheel instance in the level prefab instance.
- InstanceAlias wheelInstanceAlias = FindNestedInstanceAliasInInstance(GetRootContainerEntityId(), wheelPrefabName);
- ValidateNestedInstanceUnderInstance(GetRootContainerEntityId(), wheelInstanceAlias);
- InstanceOptionalReference levelInstance = m_instanceEntityMapperInterface->FindOwningInstance(GetRootContainerEntityId());
- ASSERT_TRUE(levelInstance.has_value());
- AZStd::vector<InstanceOptionalReference> nestedInstances;
- levelInstance->get().GetNestedInstances(
- [&nestedInstances](AZStd::unique_ptr<Instance>& nestedInstance)
- {
- nestedInstances.push_back(*(nestedInstance.get()));
- });
- EXPECT_EQ(nestedInstances.size(), 1) << "There should be only one nested instance in level after detaching.";
- EXPECT_TRUE(nestedInstances[0].has_value());
- // Validate that the car is gone
- AZStd::string carEntityAliasAfterDetach = FindEntityAliasInInstance(GetRootContainerEntityId(), carPrefabName);
- AZ::EntityId carEntityIdAfterDetach = levelInstance->get().GetEntityId(carEntityAliasAfterDetach);
- EXPECT_FALSE(carEntityIdAfterDetach.IsValid());
- // Validate that the wheels' parent entity is the level instance.
- AZ::EntityId wheelsEntityIdAfterDetach = levelInstance->get().GetEntityId(wheelsEntityAlias);
- EXPECT_TRUE(wheelsEntityIdAfterDetach.IsValid());
- AZ::EntityId parentEntityIdForWheels;
- AZ::TransformBus::EventResult(parentEntityIdForWheels, wheelsEntityIdAfterDetach, &AZ::TransformInterface::GetParentId);
- EXPECT_EQ(levelInstance->get().GetContainerEntityId(), parentEntityIdForWheels);
- // Validate that the wheel prefab's container entity is the "wheels" entity.
- Instance& wheelInstanceAfterDetach = nestedInstances[0]->get();
- AZ::EntityId wheelContainerIdAfterDetach = wheelInstanceAfterDetach.GetContainerEntityId();
- EXPECT_TRUE(wheelContainerIdAfterDetach.IsValid());
- AZ::EntityId parentEntityIdForWheel;
- AZ::TransformBus::EventResult(parentEntityIdForWheel, wheelContainerIdAfterDetach, &AZ::TransformInterface::GetParentId);
- EXPECT_EQ(wheelsEntityIdAfterDetach, parentEntityIdForWheel);
- }
- TEST_F(PrefabDetachPrefabTests, DetachPrefabAndRemoveContainerEntityValidatesDetachedContainerEntityOrder)
- {
- // Validate the detached container entity's sort order in its parent.
- // The detached container entity should not be moved to the beginning or end of the child entity list.
- //
- // Level
- // | Station
- // | Car (prefab) <-- detach prefab
- // | Tire
- // | House
- // result (car is gone)
- // The detached container entity should not be moved to the beginning or end of the child entity list.
- //
- // Level
- // | Station
- // | Tire
- // | House
- const AZStd::string carPrefabName = "CarPrefab";
- const AZStd::string tireEntityName = "Tire";
- const AZStd::string stationEntityName = "Station";
- const AZStd::string houseEntityName = "House";
- AZ::IO::Path engineRootPath;
- m_settingsRegistryInterface->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
- AZ::IO::Path carPrefabFilepath = engineRootPath / carPrefabName;
- CreateEditorEntityUnderRoot(stationEntityName);
- AZ::EntityId tireEntityId = CreateEditorEntityUnderRoot(tireEntityName);
- AZ::EntityId carContainerId = CreateEditorPrefab(carPrefabFilepath, { tireEntityId });
- CreateEditorEntityUnderRoot(houseEntityName);
- // Validate child entity order before detaching the car prefab.
- AzToolsFramework::EntityOrderArray entityOrderArrayBeforeDetach =
- AzToolsFramework::GetEntityChildOrder(GetRootContainerEntityId());
- EXPECT_EQ(entityOrderArrayBeforeDetach.size(), 3);
- AZStd::string childEntityName;
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayBeforeDetach[0]);
- EXPECT_EQ(childEntityName, stationEntityName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayBeforeDetach[1]);
- EXPECT_EQ(childEntityName, carPrefabName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayBeforeDetach[2]);
- EXPECT_EQ(childEntityName, houseEntityName);
- // Detach the car prefab.
- PrefabOperationResult result = m_prefabPublicInterface->DetachPrefabAndRemoveContainerEntity(carContainerId);
- ASSERT_TRUE(result.IsSuccess());
- PropagateAllTemplateChanges();
- // Validate child entity order after detaching the car prefab.
- AzToolsFramework::EntityOrderArray entityOrderArrayAfterDetach =
- AzToolsFramework::GetEntityChildOrder(GetRootContainerEntityId());
- EXPECT_EQ(entityOrderArrayAfterDetach.size(), 3);
- childEntityName = "";
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayAfterDetach[0]);
- EXPECT_EQ(childEntityName, stationEntityName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayAfterDetach[1]);
- EXPECT_EQ(childEntityName, tireEntityName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayAfterDetach[2]);
- EXPECT_EQ(childEntityName, houseEntityName);
- }
- TEST_F(PrefabDetachPrefabTests, DetachPrefabAndRemoveContainerEntityValidatesDetachedChildEntityOrder)
- {
- // Validate the sort order of top-level child entities.
-
- // Level
- // Car (prefab) child 0
- // Engine
- // Wheel (prefab)
- // Tire
- // Battery
- // expected result (car is gone)
- // Level
- // Engine child 0
- // Wheel (prefab) child 1
- // Tire
- // Battery child 2
- const AZStd::string carPrefabName = "CarPrefab";
- const AZStd::string wheelPrefabName = "WheelPrefab";
- const AZStd::string tireEntityName = "Tire";
- const AZStd::string engineEntityName = "Engine";
- const AZStd::string batteryEntityName = "Battery";
- AZ::IO::Path engineRootPath;
- m_settingsRegistryInterface->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
- AZ::IO::Path carPrefabFilepath = engineRootPath / carPrefabName;
- AZ::IO::Path wheelPrefabFilepath = engineRootPath / wheelPrefabName;
- AZ::EntityId engineEntityId = CreateEditorEntityUnderRoot(engineEntityName);
- AZ::EntityId tireEntityId = CreateEditorEntityUnderRoot(tireEntityName);
- AZ::EntityId wheelContainerId = CreateEditorPrefab(wheelPrefabFilepath, { tireEntityId });
- AZ::EntityId batteryEntityId = CreateEditorEntityUnderRoot(batteryEntityName);
- AZ::EntityId carContainerId = CreateEditorPrefab(carPrefabFilepath, { engineEntityId, wheelContainerId, batteryEntityId });
- // Validate child entity order under car before detaching the car prefab.
- AzToolsFramework::EntityOrderArray entityOrderArrayBeforeDetach = AzToolsFramework::GetEntityChildOrder(carContainerId);
- EXPECT_EQ(entityOrderArrayBeforeDetach.size(), 3);
- AZStd::string childEntityName;
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayBeforeDetach[0]);
- EXPECT_EQ(childEntityName, engineEntityName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayBeforeDetach[1]);
- EXPECT_EQ(childEntityName, wheelPrefabName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayBeforeDetach[2]);
- EXPECT_EQ(childEntityName, batteryEntityName);
- InstanceOptionalReference levelInstance = m_instanceEntityMapperInterface->FindOwningInstance(GetRootContainerEntityId());
- ASSERT_TRUE(levelInstance.has_value());
- // before we detach, the level should contain 1 entity (the container entity) and 1 instance (of the car)
- int count = 0;
- levelInstance->get().GetEntityIds([&count](AZ::EntityId) { count++; return true; });
- EXPECT_EQ(count, 1); // expect 1 real entity, that is, the container for the car.
- count = 0;
- levelInstance->get().GetNestedInstances([&count](AZStd::unique_ptr<Instance>&) { count++; });
- EXPECT_EQ(count, 1); // expect 1 instance of another prefab (The the car)
- // Detach the car prefab.
- PrefabOperationResult result = m_prefabPublicInterface->DetachPrefabAndRemoveContainerEntity(carContainerId);
- ASSERT_TRUE(result.IsSuccess());
- PropagateAllTemplateChanges();
- // after we detach, the level should contain 3 entities (2 of them real entities, one of them an instance container)
- count = 0;
- levelInstance->get().GetEntityIds([&count](const AZ::EntityId&) { count++; return true; });
- EXPECT_EQ(count, 3); // expect 2 REAL entities.
- count = 0;
- levelInstance->get().GetNestedInstances([&count](AZStd::unique_ptr<Instance>&) { count++; });
- EXPECT_EQ(count, 1); // expect 1 instance of another prefab (the wheel)
- // Validate child entity order under the level after detaching the car prefab. Should be engine, wheel, battery.
- AzToolsFramework::EntityOrderArray entityOrderArrayAfterDetach =
- AzToolsFramework::GetEntityChildOrder(levelInstance->get().GetContainerEntityId());
- EXPECT_EQ(entityOrderArrayAfterDetach.size(), 3);
- childEntityName = "";
- AZ::ComponentApplicationBus::BroadcastResult(childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayAfterDetach[0]);
- EXPECT_EQ(childEntityName, engineEntityName);
- AZ::ComponentApplicationBus::BroadcastResult(childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayAfterDetach[1]);
- EXPECT_EQ(childEntityName, wheelPrefabName);
- AZ::ComponentApplicationBus::BroadcastResult(childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayAfterDetach[2]);
- EXPECT_EQ(childEntityName, batteryEntityName);
- }
- TEST_F(PrefabDetachPrefabTests, DetachPrefabAndRemoveContainerEntityValidatesTopLevelChildEntityOrder)
- {
- // Validate the sort order of child entities and prefabs that are under the top level entity.
- //
- // Level
- // | Car (prefab) <-- detach prefab
- // | Wheels <-- top level entity
- // | Red_Wheel
- // | Wheel (prefab)
- // | Tire
- // | Black_Wheel
- //
- // expected result (car is gone)
- // Level
- // | Wheels <-- top level entity
- // | Red_Wheel
- // | Wheel (prefab)
- // | Tire
- // | Black_Wheel
- const AZStd::string carPrefabName = "CarPrefab";
- const AZStd::string wheelPrefabName = "WheelPrefab";
- const AZStd::string wheelsEntityName = "Wheels";
- const AZStd::string redWheelEntityName = "Red_Wheel";
- const AZStd::string blackWheelEntityName = "Black_Wheel";
- const AZStd::string tireEntityName = "Tire";
- AZ::IO::Path engineRootPath;
- m_settingsRegistryInterface->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
- AZ::IO::Path carPrefabFilepath = engineRootPath / carPrefabName;
- AZ::IO::Path wheelPrefabFilepath = engineRootPath / wheelPrefabName;
- // Create the wheels, red wheel and tire entities.
- AZ::EntityId wheelsEntityId = CreateEditorEntityUnderRoot(wheelsEntityName);
- CreateEditorEntity(redWheelEntityName, wheelsEntityId);
- AZ::EntityId tireEntityId = CreateEditorEntity(tireEntityName, wheelsEntityId);
- // Create the wheel prefab.
- CreateEditorPrefab(wheelPrefabFilepath, { tireEntityId });
- // Create the black wheel entity.
- CreateEditorEntity(blackWheelEntityName, wheelsEntityId);
- // Create the car prefab.
- AZ::EntityId carContainerId = CreateEditorPrefab(carPrefabFilepath, { wheelsEntityId });
- InstanceOptionalReference levelInstance = m_instanceEntityMapperInterface->FindOwningInstance(GetRootContainerEntityId());
- ASSERT_TRUE(levelInstance.has_value());
- // Validate child entity order under wheels before detaching the car prefab.
- EntityAlias wheelsEntityAlias = FindEntityAliasInInstance(carContainerId, wheelsEntityName);
- InstanceOptionalReference carInstance = m_instanceEntityMapperInterface->FindOwningInstance(carContainerId);
- EXPECT_TRUE(carInstance.has_value());
- wheelsEntityId = carInstance->get().GetEntityId(wheelsEntityAlias);
- AzToolsFramework::EntityOrderArray entityOrderArrayBeforeDetach = AzToolsFramework::GetEntityChildOrder(wheelsEntityId);
- EXPECT_EQ(entityOrderArrayBeforeDetach.size(), 3);
- AZStd::string childEntityName;
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayBeforeDetach[0]);
- EXPECT_EQ(childEntityName, redWheelEntityName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayBeforeDetach[1]);
- EXPECT_EQ(childEntityName, wheelPrefabName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayBeforeDetach[2]);
- EXPECT_EQ(childEntityName, blackWheelEntityName);
- // Detach the car prefab.
- PrefabOperationResult result = m_prefabPublicInterface->DetachPrefabAndRemoveContainerEntity(carContainerId);
- ASSERT_TRUE(result.IsSuccess());
- PropagateAllTemplateChanges();
- // Validate child entity order under wheels after detaching the car prefab.
- wheelsEntityAlias = FindEntityAliasInInstance(levelInstance->get().GetContainerEntityId(), wheelsEntityName);
- wheelsEntityId = levelInstance->get().GetEntityId(wheelsEntityAlias);
- AzToolsFramework::EntityOrderArray entityOrderArrayAfterDetach = AzToolsFramework::GetEntityChildOrder(wheelsEntityId);
- EXPECT_EQ(entityOrderArrayAfterDetach.size(), 3);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayAfterDetach[0]);
- EXPECT_EQ(childEntityName, redWheelEntityName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayAfterDetach[1]);
- EXPECT_EQ(childEntityName, wheelPrefabName);
- AZ::ComponentApplicationBus::BroadcastResult(
- childEntityName, &AZ::ComponentApplicationRequests::GetEntityName, entityOrderArrayAfterDetach[2]);
- EXPECT_EQ(childEntityName, blackWheelEntityName);
- }
- } // namespace UnitTest
|