From 48c34628f60c1475a4f2d377604a83a3ef6a43d2 Mon Sep 17 00:00:00 2001 From: daimini Date: Wed, 28 Apr 2021 13:34:02 -0700 Subject: [PATCH 1/3] Exclude the Level root prefab container when creating prefabs. --- .../Prefab/PrefabPublicHandler.cpp | 22 +++++++--- .../UI/Prefab/PrefabIntegrationManager.cpp | 42 ++++++++++--------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 1e9cc35230..46c3eaefe4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -89,7 +89,7 @@ namespace AzToolsFramework if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances)) { return AZ::Failure( - AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root.")); + AZStd::string("Could not create a new prefab out of the entities provided - invalid selection.")); } // When we create a prefab with other prefab instances, we have to remove the existing links between the source and @@ -142,9 +142,13 @@ namespace AzToolsFramework // Mark them as dirty so this change is correctly applied to the template for (AZ::Entity* topLevelEntity : topLevelEntities) { - m_prefabUndoCache.UpdateCache(topLevelEntity->GetId()); - undoBatch.MarkEntityDirty(topLevelEntity->GetId()); - AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); + AZ::EntityId topLevelEntityId = topLevelEntity->GetId(); + if (topLevelEntityId.IsValid() && !IsLevelInstanceContainerEntity(topLevelEntityId)) + { + m_prefabUndoCache.UpdateCache(topLevelEntityId); + undoBatch.MarkEntityDirty(topLevelEntityId); + AZ::TransformBus::Event(topLevelEntityId, &AZ::TransformBus::Events::SetParent, containerEntityId); + } } // Select Container Entity @@ -223,6 +227,14 @@ namespace AzToolsFramework // Retrieve entityList from entityIds inputEntityList = EntityIdListToEntityList(entityIds); + // Remove Level Container Entity if it's part of the list + AZ::Entity* levelEntity = GetEntityById(GetLevelInstanceContainerEntityId()); + auto levelEntityIter = AZStd::find(inputEntityList.begin(), inputEntityList.end(), levelEntity); + if (levelEntityIter != inputEntityList.end()) + { + inputEntityList.erase(levelEntityIter); + } + // Find common root and top level entities bool entitiesHaveCommonRoot = false; @@ -840,7 +852,7 @@ namespace AzToolsFramework outInstances.push_back(AZStd::move(commonRootEntityOwningInstance.DetachNestedInstance(instancePtr->GetInstanceAlias()))); } - return true; + return (outEntities.size() + outInstances.size()) > 0; } bool PrefabPublicHandler::EntitiesBelongToSameInstance(const EntityIdList& entityIds) const diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp index 6ce3fdc755..71354b8a1b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp @@ -151,32 +151,36 @@ namespace AzToolsFramework { if (!selectedEntities.empty()) { - bool layerInSelection = false; - - for (AZ::EntityId entityId : selectedEntities) + // Hide if the only selected entity is the Level Container + if (selectedEntities.size() > 1 || !s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntities[0])) { - if (!layerInSelection) - { - AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult( - layerInSelection, entityId, - &AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::HasLayer); + bool layerInSelection = false; - if (layerInSelection) + for (AZ::EntityId entityId : selectedEntities) + { + if (!layerInSelection) { - break; + AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult( + layerInSelection, entityId, + &AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::HasLayer); + + if (layerInSelection) + { + break; + } } } - } - // Layers can't be in prefabs. - if (!layerInSelection) - { - QAction* createAction = menu->addAction(QObject::tr("Create Prefab...")); - createAction->setToolTip(QObject::tr("Creates a prefab out of the currently selected entities.")); + // Layers can't be in prefabs. + if (!layerInSelection) + { + QAction* createAction = menu->addAction(QObject::tr("Create Prefab...")); + createAction->setToolTip(QObject::tr("Creates a prefab out of the currently selected entities.")); - QObject::connect(createAction, &QAction::triggered, createAction, [this, selectedEntities] { - ContextMenu_CreatePrefab(selectedEntities); - }); + QObject::connect(createAction, &QAction::triggered, createAction, [this, selectedEntities] { + ContextMenu_CreatePrefab(selectedEntities); + }); + } } } } From 6271aaa77ff3beee79c183ecd7baf3bf38544b5b Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 29 Apr 2021 11:07:15 -0700 Subject: [PATCH 2/3] Exclude level container entity from prefab external reference gathering code --- .../UI/Prefab/PrefabIntegrationManager.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp index 71354b8a1b..7f28080e9e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp @@ -276,6 +276,15 @@ namespace AzToolsFramework QWidget* activeWindow = QApplication::activeWindow(); const AZStd::string prefabFilesPath = "@devassets@/Prefabs"; + // Remove Level entity if it's part of the list + + auto levelContainerIter = + AZStd::find(selectedEntities.begin(), selectedEntities.end(), s_prefabPublicInterface->GetLevelInstanceContainerEntityId()); + if (levelContainerIter != selectedEntities.end()) + { + selectedEntities.erase(levelContainerIter); + } + // Set default folder for prefabs AZ::IO::FileIOBase* fileIoBaseInstance = AZ::IO::FileIOBase::GetInstance(); From e22398700dc45d2f5be50c8e23f6d4fb89323698 Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 29 Apr 2021 16:19:58 -0700 Subject: [PATCH 3/3] Simplified some checks, added early outs. --- .../Prefab/PrefabPublicHandler.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 46c3eaefe4..da4eee2263 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -143,7 +143,7 @@ namespace AzToolsFramework for (AZ::Entity* topLevelEntity : topLevelEntities) { AZ::EntityId topLevelEntityId = topLevelEntity->GetId(); - if (topLevelEntityId.IsValid() && !IsLevelInstanceContainerEntity(topLevelEntityId)) + if (topLevelEntityId.IsValid()) { m_prefabUndoCache.UpdateCache(topLevelEntityId); undoBatch.MarkEntityDirty(topLevelEntityId); @@ -228,11 +228,18 @@ namespace AzToolsFramework inputEntityList = EntityIdListToEntityList(entityIds); // Remove Level Container Entity if it's part of the list - AZ::Entity* levelEntity = GetEntityById(GetLevelInstanceContainerEntityId()); - auto levelEntityIter = AZStd::find(inputEntityList.begin(), inputEntityList.end(), levelEntity); - if (levelEntityIter != inputEntityList.end()) + AZ::EntityId levelEntityId = GetLevelInstanceContainerEntityId(); + if (levelEntityId.IsValid()) { - inputEntityList.erase(levelEntityIter); + AZ::Entity* levelEntity = GetEntityById(levelEntityId); + if (levelEntity) + { + auto levelEntityIter = AZStd::find(inputEntityList.begin(), inputEntityList.end(), levelEntity); + if (levelEntityIter != inputEntityList.end()) + { + inputEntityList.erase(levelEntityIter); + } + } } // Find common root and top level entities @@ -765,6 +772,11 @@ namespace AzToolsFramework const EntityList& inputEntities, Instance& commonRootEntityOwningInstance, EntityList& outEntities, AZStd::vector>& outInstances) const { + if (inputEntities.size() == 0) + { + return false; + } + AZStd::queue entityQueue; for (auto inputEntity : inputEntities)