diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h index 30ffb461fa..1a5ba60bdf 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h @@ -201,11 +201,8 @@ namespace AzToolsFramework //! Fired after the EditorEntityContext fails to export the root level slice to the game stream virtual void OnSaveStreamForGameFailure(AZStd::string_view /*failureString*/) {} - //! Fired when the user triggers a clone of ComponentEntity object(s), before operation begins - virtual void OnEntitiesAboutToBeCloned() {} - - //! Fires when the user triggers a clone of ComponentEntity object(s)), after operation completes - virtual void OnEntitiesCloned() {} + //! Preserve entity order when re-parenting entities + virtual void SetForceAddEntitiesToBackFlag(bool /*forceAddToBack*/) {} }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp index 3e256430a2..dc0f5e9654 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp @@ -1157,7 +1157,7 @@ namespace AzToolsFramework bool CloneInstantiatedEntities(const EntityIdSet& entitiesToClone, EntityIdSet& clonedEntities) { - EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnEntitiesAboutToBeCloned); + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, true); ScopedUndoBatch undoBatch("Clone Selection"); // Track the mapping of source to cloned entity. This both helps make sure that an entity is not accidentally @@ -1199,7 +1199,7 @@ namespace AzToolsFramework // Also replace the selection with the entities that have been cloned. Internal::UpdateUndoStackAndSelectClonedEntities(allEntityClonesContainer.m_entities, undoBatch); - EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnEntitiesCloned); + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, false); for (const AZ::Entity* entity : allEntityClonesContainer.m_entities) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp index e4d4f40bce..adf062875e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp @@ -643,14 +643,9 @@ namespace AzToolsFramework } } - void EditorEntityModel::OnEntitiesAboutToBeCloned() + void EditorEntityModel::SetForceAddEntitiesToBackFlag(bool forceAddToBack) { - m_forceAddToBack = true; - } - - void EditorEntityModel::OnEntitiesCloned() - { - m_forceAddToBack = false; + m_forceAddToBack = forceAddToBack; } void EditorEntityModel::ChildEntityOrderArrayUpdated() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h index 45d3d4ea59..c2574a9940 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h @@ -94,9 +94,7 @@ namespace AzToolsFramework void OnEntityStreamLoadBegin() override; void OnEntityStreamLoadSuccess() override; void OnEntityStreamLoadFailed() override; - void OnEntitiesAboutToBeCloned() override; - void OnEntitiesCloned() override; - + void SetForceAddEntitiesToBackFlag(bool forceAddToBack) override; //////////////////////////////////////////////// // AzFramework::EntityContextEventBus::Handler diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index aaf6141e12..bde5de2f64 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -83,6 +84,20 @@ namespace AzToolsFramework return AZ::Failure(findCommonRootOutcome.TakeError()); } + // order entities by their respective position within Entity Outliner + EditorEntitySortRequestBus::Event( + commonRootEntityId, + [&topLevelEntities](EditorEntitySortRequestBus::Events* sortRequests) + { + AZStd::sort( + topLevelEntities.begin(), topLevelEntities.end(), + [&sortRequests](AZ::Entity* entity1, AZ::Entity* entity2) + { + return sortRequests->GetChildEntityIndex(entity1->GetId()) < + sortRequests->GetChildEntityIndex(entity2->GetId()); + }); + }); + AZ::EntityId containerEntityId; InstanceOptionalReference instanceToCreate; @@ -153,8 +168,6 @@ namespace AzToolsFramework } // Create the Prefab - AZ_Assert(filePath.IsAbsolute(), "CreatePrefabInMemory requires an absolute file path."); - instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab( entities, AZStd::move(instancePtrs), m_prefabLoaderInterface->GenerateRelativePath(filePath), commonRootEntityOwningInstance); @@ -172,6 +185,7 @@ namespace AzToolsFramework // Parent the non-container top level entities to the container entity. // Parenting the top level container entities will be done during the creation of links. + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, true); for (AZ::Entity* topLevelEntity : topLevelEntities) { if (!IsInstanceContainerEntity(topLevelEntity->GetId())) @@ -179,6 +193,7 @@ namespace AzToolsFramework AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); } } + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, false); // Update the template of the instance since the entities are modified since the template creation. Prefab::PrefabDom serializedInstance; @@ -279,6 +294,8 @@ namespace AzToolsFramework CreatePrefabResult PrefabPublicHandler::CreatePrefabInDisk(const EntityIdList& entityIds, AZ::IO::PathView filePath) { + AZ_Assert(filePath.IsAbsolute(), "CreatePrefabInDisk requires an absolute file path."); + auto result = CreatePrefabInMemory(entityIds, filePath); if (result.IsSuccess()) {