From ca8d6f88187831c1c958aff1447ddff2028d0bf0 Mon Sep 17 00:00:00 2001 From: daimini Date: Wed, 21 Apr 2021 17:42:33 -0700 Subject: [PATCH 1/8] Instantiate Prefab --- .../PrefabEditorEntityOwnershipInterface.h | 9 +- .../PrefabEditorEntityOwnershipService.cpp | 27 ++++ .../PrefabEditorEntityOwnershipService.h | 5 + .../Prefab/PrefabPublicHandler.cpp | 128 +++++++++++++----- .../Prefab/PrefabSystemComponent.cpp | 23 ++++ .../Prefab/PrefabSystemComponent.h | 9 +- .../Prefab/PrefabSystemComponentInterface.h | 1 + 7 files changed, 166 insertions(+), 36 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h index f272c3b428..9dc3fc16f7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h @@ -31,11 +31,18 @@ namespace AzToolsFramework //! /param entities The entities to put under the new prefab. //! /param nestedPrefabInstances The nested prefab instances to put under the new prefab. //! /param filePath The filepath corresponding to the prefab file to be created. - //! /param instanceToParentUnder The instance under which the newly created prefab instance is parented under. + //! /param instanceToParentUnder The instance the newly created prefab instance is parented under. //! /return The optional reference to the prefab created. virtual Prefab::InstanceOptionalReference CreatePrefab( const AZStd::vector& entities, AZStd::vector>&& nestedPrefabInstances, AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0; + + //! Instantiate the prefab file provided. + //! /param entityToParentUnder The entity the newly created prefab instance is parented under. + //! /return The optional reference to the prefab instance. + virtual Prefab::InstanceOptionalReference InstantiatePrefab( + AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0; + virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0; virtual bool LoadFromStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index cb16e0c099..93e90efe96 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,10 @@ namespace AzToolsFramework AZ_Assert(m_loaderInterface != nullptr, "Couldn't get prefab loader interface, it's a requirement for PrefabEntityOwnership system to work"); + m_instanceEntityMapperInterface = AZ::Interface::Get(); + AZ_Assert(m_instanceEntityMapperInterface != nullptr, + "Couldn't get instance entity mapper interface, it's a requirement for PrefabEntityOwnership system to work"); + m_rootInstance = AZStd::unique_ptr(m_prefabSystemComponent->CreatePrefab({}, {}, "NewLevel.prefab")); m_sliceOwnershipService.BusConnect(m_entityContextId); @@ -307,6 +312,28 @@ namespace AzToolsFramework return AZStd::nullopt; } + Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::InstantiatePrefab( + AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) + { + AZStd::unique_ptr createdPrefabInstance = m_prefabSystemComponent->InstantiatePrefab(filePath); + + if (createdPrefabInstance) + { + if (!instanceToParentUnder) + { + instanceToParentUnder = *m_rootInstance; + } + + Prefab::Instance& addedInstance = instanceToParentUnder->get().AddInstance(AZStd::move(createdPrefabInstance)); + AZ::Entity* containerEntity = addedInstance.m_containerEntity.get(); + HandleEntitiesAdded({containerEntity}); + + return addedInstance; + } + + return AZStd::nullopt; + } + Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::GetRootPrefabInstance() { AZ_Assert(m_rootInstance, "A valid root prefab instance couldn't be found in PrefabEditorEntityOwnershipService."); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h index 36a60cc501..2c66c691b6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h @@ -25,6 +25,7 @@ namespace AzToolsFramework namespace Prefab { class Instance; + class InstanceEntityMapperInterface; class PrefabSystemComponentInterface; class PrefabLoaderInterface; } @@ -191,6 +192,9 @@ namespace AzToolsFramework const AZStd::vector& entities, AZStd::vector>&& nestedPrefabInstances, AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) override; + Prefab::InstanceOptionalReference InstantiatePrefab( + AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) override; + Prefab::InstanceOptionalReference GetRootPrefabInstance() override; ////////////////////////////////////////////////////////////////////////// @@ -205,6 +209,7 @@ namespace AzToolsFramework AZStd::string m_rootPath; AZStd::unique_ptr m_rootInstance; + Prefab::InstanceEntityMapperInterface* m_instanceEntityMapperInterface; Prefab::PrefabSystemComponentInterface* m_prefabSystemComponent; Prefab::PrefabLoaderInterface* m_loaderInterface; AzFramework::EntityContextId m_entityContextId; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 772e0ae52e..aef757d521 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -149,6 +149,57 @@ namespace AzToolsFramework return AZ::Success(); } + PrefabOperationResult PrefabPublicHandler::InstantiatePrefab( + AZStd::string_view filePath, AZ::EntityId parent, AZ::Vector3 /*position*/) + { + auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get(); + if (!prefabEditorEntityOwnershipInterface) + { + return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error " + "(PrefabEditorEntityOwnershipInterface unavailable).")); + } + + auto instanceToParentUnder = m_instanceEntityMapperInterface->FindOwningInstance(parent); + + if (!instanceToParentUnder) + { + instanceToParentUnder = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance(); + if (!parent.IsValid()) + { + parent = instanceToParentUnder->get().GetContainerEntityId(); + } + } + + { + // Initialize Undo Batch object + ScopedUndoBatch undoBatch("Initialize Prefab"); + + PrefabDom instanceToParentUnderDomBeforeCreate; + m_instanceToTemplateInterface->GenerateDomForInstance( + instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get()); + + // Instantiate the Prefab + auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(filePath, instanceToParentUnder); + + if (!instanceToCreate) + { + return AZ::Failure(AZStd::string("Could not instantiate the prefab provided - internal error " + "(A null instance is returned).")); + } + + PrefabUndoHelpers::UpdatePrefabInstance( + instanceToParentUnder->get(), "Update prefab instance", instanceToParentUnderDomBeforeCreate, undoBatch.GetUndoBatch()); + + CreateLink({GetEntityById(parent)}, instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), + undoBatch.GetUndoBatch(), parent); + AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId(); + + // TODO - apply position + } + + return AZ::Success(); + } + PrefabOperationResult PrefabPublicHandler::FindCommonRootOwningInstance( const AZStd::vector& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities, AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance) @@ -210,19 +261,16 @@ namespace AzToolsFramework m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter); m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId); - PrefabUndoHelpers::CreateLink( + LinkId linkId = PrefabUndoHelpers::CreateLink( sourceInstance.GetTemplateId(), targetTemplateId, patch, sourceInstance.GetInstanceAlias(), undoBatch); + sourceInstance.SetLinkId(linkId); + // Update the cache - this prevents these changes from being stored in the regular undo/redo nodes m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter)); } - PrefabOperationResult PrefabPublicHandler::InstantiatePrefab(AZStd::string_view /*filePath*/, AZ::EntityId /*parent*/, AZ::Vector3 /*position*/) - { - return AZ::Failure(AZStd::string("Prefab - InstantiatePrefab is yet to be implemented.")); - } - PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath) { auto prefabSystemComponentInterface = AZ::Interface::Get(); @@ -318,45 +366,57 @@ namespace AzToolsFramework return AZ::Success(entityId); } - void PrefabPublicHandler::GenerateUndoNodesForEntityChangeAndUpdateCache( - AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch) +void PrefabPublicHandler::GenerateUndoNodesForEntityChangeAndUpdateCache( + AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch) +{ + // Create Undo node on entities if they belong to an instance + InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId); + + if (owningInstance.has_value()) + { + PrefabDom afterState; + AZ::Entity* entity = GetEntityById(entityId); + if (entity) { - // Create Undo node on entities if they belong to an instance - InstanceOptionalReference instanceOptionalReference = m_instanceEntityMapperInterface->FindOwningInstance(entityId); + PrefabDom beforeState; + m_prefabUndoCache.Retrieve(entityId, beforeState); - if (instanceOptionalReference.has_value()) + m_instanceToTemplateInterface->GenerateDomForEntity(afterState, *entity); + + PrefabDom patch; + m_instanceToTemplateInterface->GeneratePatch(patch, beforeState, afterState); + + if (patch.IsArray() && !patch.Empty() && beforeState.IsObject()) { - PrefabDom afterState; - AZ::Entity* entity = GetEntityById(entityId); - if (entity) + if (IsInstanceContainerEntity(entityId) && !IsLevelInstanceContainerEntity(entityId)) { - PrefabDom beforeState; - m_prefabUndoCache.Retrieve(entityId, beforeState); + // Save these changes as patches to the link + PrefabUndoLinkUpdate* linkUpdate = aznew PrefabUndoLinkUpdate(AZStd::to_string(static_cast(entityId))); + linkUpdate->SetParent(parentUndoBatch); + linkUpdate->Capture(patch, owningInstance->get().GetLinkId()); - m_instanceToTemplateInterface->GenerateDomForEntity(afterState, *entity); - - PrefabDom patch; - m_instanceToTemplateInterface->GeneratePatch(patch, beforeState, afterState); - - if (patch.IsArray() && !patch.Empty() && beforeState.IsObject()) - { - // Update the state of the entity - PrefabUndoEntityUpdate* state = aznew PrefabUndoEntityUpdate(AZStd::to_string(static_cast(entityId))); - state->SetParent(parentUndoBatch); - state->Capture(beforeState, afterState, entityId); - - state->Redo(); - } - - // Update the cache - m_prefabUndoCache.Store(entityId, AZStd::move(afterState)); + linkUpdate->Redo(); } else { - m_prefabUndoCache.PurgeCache(entityId); + // Update the state of the entity + PrefabUndoEntityUpdate* state = aznew PrefabUndoEntityUpdate(AZStd::to_string(static_cast(entityId))); + state->SetParent(parentUndoBatch); + state->Capture(beforeState, afterState, entityId); + + state->Redo(); } } + + // Update the cache + m_prefabUndoCache.Store(entityId, AZStd::move(afterState)); } + else + { + m_prefabUndoCache.PurgeCache(entityId); + } + } +} bool PrefabPublicHandler::IsInstanceContainerEntity(AZ::EntityId entityId) const { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index 54e99c9416..3f125ca9a2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -260,6 +260,29 @@ namespace AzToolsFramework } } + AZStd::unique_ptr PrefabSystemComponent::InstantiatePrefab(AZ::IO::PathView filePath) + { + // Retrieve the template id for the source prefab filepath + Prefab::TemplateId templateId = GetTemplateIdFromFilePath(filePath); + + if (templateId == Prefab::InvalidTemplateId) + { + // Load the template from the file + templateId = m_prefabLoader.LoadTemplateFromFile(filePath); + } + + if (templateId == Prefab::InvalidTemplateId) + { + AZ_Error("Prefab", false, + "Could not load template from path %s during InstantiatePrefab. Unable to proceed", + filePath); + + return nullptr; + } + + return InstantiatePrefab(templateId); + } + AZStd::unique_ptr PrefabSystemComponent::InstantiatePrefab(const TemplateId& templateId) { TemplateReference instantiatingTemplate = FindTemplate(templateId); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h index 40780b9775..3dfbab2296 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h @@ -115,9 +115,16 @@ namespace AzToolsFramework */ void RemoveAllTemplates() override; + /** + * Generates a new Prefab Instance based on the Template whose source is stored in filepath. + * @param filePath the path to the prefab source file containing the template being instantiated. + * @return A unique_ptr to the newly instantiated instance. Null if operation failed. + */ + AZStd::unique_ptr InstantiatePrefab(AZ::IO::PathView filePath) override; + /** * Generates a new Prefab Instance based on the Template referenced by templateId - * @param templateId the id of the template being instantiated + * @param templateId the id of the template being instantiated. * @return A unique_ptr to the newly instantiated instance. Null if operation failed. */ AZStd::unique_ptr InstantiatePrefab(const TemplateId& templateId) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h index 8b94935cc1..1af2748c9b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h @@ -58,6 +58,7 @@ namespace AzToolsFramework virtual void UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom) = 0; virtual void PropagateTemplateChanges(TemplateId templateId) = 0; + virtual AZStd::unique_ptr InstantiatePrefab(AZ::IO::PathView filePath) = 0; virtual AZStd::unique_ptr InstantiatePrefab(const TemplateId& templateId) = 0; virtual AZStd::unique_ptr CreatePrefab(const AZStd::vector& entities, AZStd::vector>&& instancesToConsume, AZ::IO::PathView filePath, From 67fa4a332b1d072c10ad6c925554ad493c49ecf2 Mon Sep 17 00:00:00 2001 From: daimini Date: Wed, 21 Apr 2021 17:43:22 -0700 Subject: [PATCH 2/8] Change CreateLink to return the LinkId --- .../AzToolsFramework/Prefab/PrefabUndoHelpers.cpp | 4 +++- .../AzToolsFramework/Prefab/PrefabUndoHelpers.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp index c9b6c88a97..2062e8b12c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp @@ -33,7 +33,7 @@ namespace AzToolsFramework state->Redo(); } - void CreateLink( + LinkId CreateLink( TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch, const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch) { @@ -41,6 +41,8 @@ namespace AzToolsFramework linkAddUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, patch, InvalidLinkId); linkAddUndo->SetParent(undoBatch); linkAddUndo->Redo(); + + return linkAddUndo->GetLinkId(); } void RemoveLink( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.h index 5f81ef14a8..74532b87a2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.h @@ -21,7 +21,7 @@ namespace AzToolsFramework void UpdatePrefabInstance( const Instance& instance, AZStd::string_view undoMessage, const PrefabDom& instanceDomBeforeUpdate, UndoSystem::URSequencePoint* undoBatch); - void CreateLink( + LinkId CreateLink( TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch, const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch); void RemoveLink( From cf4bbe569be7ef596f447b686c4754c5889f9bfe Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 22 Apr 2021 09:47:18 -0700 Subject: [PATCH 3/8] Remove Prefab cache undo node generation for container entities - will move that work to a separate PR. --- .../Prefab/PrefabPublicHandler.cpp | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index aef757d521..8860d4b155 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -388,24 +388,12 @@ void PrefabPublicHandler::GenerateUndoNodesForEntityChangeAndUpdateCache( if (patch.IsArray() && !patch.Empty() && beforeState.IsObject()) { - if (IsInstanceContainerEntity(entityId) && !IsLevelInstanceContainerEntity(entityId)) - { - // Save these changes as patches to the link - PrefabUndoLinkUpdate* linkUpdate = aznew PrefabUndoLinkUpdate(AZStd::to_string(static_cast(entityId))); - linkUpdate->SetParent(parentUndoBatch); - linkUpdate->Capture(patch, owningInstance->get().GetLinkId()); + // Update the state of the entity + PrefabUndoEntityUpdate* state = aznew PrefabUndoEntityUpdate(AZStd::to_string(static_cast(entityId))); + state->SetParent(parentUndoBatch); + state->Capture(beforeState, afterState, entityId); - linkUpdate->Redo(); - } - else - { - // Update the state of the entity - PrefabUndoEntityUpdate* state = aznew PrefabUndoEntityUpdate(AZStd::to_string(static_cast(entityId))); - state->SetParent(parentUndoBatch); - state->Capture(beforeState, afterState, entityId); - - state->Redo(); - } + state->Redo(); } // Update the cache From c9a4b6f50ba5ef8b7097634859a4418cf92c1a40 Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 22 Apr 2021 14:53:07 -0700 Subject: [PATCH 4/8] Better handle the default case for Instantiate --- .../Prefab/PrefabPublicHandler.cpp | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 8860d4b155..aa43d81a03 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -155,24 +155,27 @@ namespace AzToolsFramework auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get(); if (!prefabEditorEntityOwnershipInterface) { - return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error " + return AZ::Failure(AZStd::string("Could not instantiate prefab - internal error " "(PrefabEditorEntityOwnershipInterface unavailable).")); } - auto instanceToParentUnder = m_instanceEntityMapperInterface->FindOwningInstance(parent); + InstanceOptionalReference instanceToParentUnder; - if (!instanceToParentUnder) + // Get parent entity and owning instance + if (parent.IsValid()) { - instanceToParentUnder = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance(); - if (!parent.IsValid()) - { - parent = instanceToParentUnder->get().GetContainerEntityId(); - } + instanceToParentUnder = m_instanceEntityMapperInterface->FindOwningInstance(parent); } + if (!instanceToParentUnder.has_value()) + { + instanceToParentUnder = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance(); + parent = instanceToParentUnder->get().GetContainerEntityId(); + } + { // Initialize Undo Batch object - ScopedUndoBatch undoBatch("Initialize Prefab"); + ScopedUndoBatch undoBatch("Instantiate Prefab"); PrefabDom instanceToParentUnderDomBeforeCreate; m_instanceToTemplateInterface->GenerateDomForInstance( From ea43eb3ac94d42c2633209b8ea833220e7187b5c Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 22 Apr 2021 15:49:13 -0700 Subject: [PATCH 5/8] Set position of instantiated prefab --- .../AzToolsFramework/Prefab/PrefabPublicHandler.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index aa43d81a03..8e965c3d6d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -150,7 +150,7 @@ namespace AzToolsFramework } PrefabOperationResult PrefabPublicHandler::InstantiatePrefab( - AZStd::string_view filePath, AZ::EntityId parent, AZ::Vector3 /*position*/) + AZStd::string_view filePath, AZ::EntityId parent, AZ::Vector3 position) { auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get(); if (!prefabEditorEntityOwnershipInterface) @@ -193,11 +193,12 @@ namespace AzToolsFramework PrefabUndoHelpers::UpdatePrefabInstance( instanceToParentUnder->get(), "Update prefab instance", instanceToParentUnderDomBeforeCreate, undoBatch.GetUndoBatch()); - CreateLink({GetEntityById(parent)}, instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), + CreateLink({}, instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), undoBatch.GetUndoBatch(), parent); AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId(); - // TODO - apply position + // Apply position + AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetWorldTranslation, position); } return AZ::Success(); From 76739de282786741dae3c4cabe6c57a3d2fd923f Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 22 Apr 2021 15:52:39 -0700 Subject: [PATCH 6/8] Fix spacing --- .../Prefab/PrefabPublicHandler.cpp | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 8e965c3d6d..2ed40e748f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -370,45 +370,45 @@ namespace AzToolsFramework return AZ::Success(entityId); } -void PrefabPublicHandler::GenerateUndoNodesForEntityChangeAndUpdateCache( - AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch) -{ - // Create Undo node on entities if they belong to an instance - InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId); - - if (owningInstance.has_value()) - { - PrefabDom afterState; - AZ::Entity* entity = GetEntityById(entityId); - if (entity) + void PrefabPublicHandler::GenerateUndoNodesForEntityChangeAndUpdateCache( + AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch) { - PrefabDom beforeState; - m_prefabUndoCache.Retrieve(entityId, beforeState); + // Create Undo node on entities if they belong to an instance + InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId); - m_instanceToTemplateInterface->GenerateDomForEntity(afterState, *entity); - - PrefabDom patch; - m_instanceToTemplateInterface->GeneratePatch(patch, beforeState, afterState); - - if (patch.IsArray() && !patch.Empty() && beforeState.IsObject()) + if (owningInstance.has_value()) { - // Update the state of the entity - PrefabUndoEntityUpdate* state = aznew PrefabUndoEntityUpdate(AZStd::to_string(static_cast(entityId))); - state->SetParent(parentUndoBatch); - state->Capture(beforeState, afterState, entityId); + PrefabDom afterState; + AZ::Entity* entity = GetEntityById(entityId); + if (entity) + { + PrefabDom beforeState; + m_prefabUndoCache.Retrieve(entityId, beforeState); - state->Redo(); + m_instanceToTemplateInterface->GenerateDomForEntity(afterState, *entity); + + PrefabDom patch; + m_instanceToTemplateInterface->GeneratePatch(patch, beforeState, afterState); + + if (patch.IsArray() && !patch.Empty() && beforeState.IsObject()) + { + // Update the state of the entity + PrefabUndoEntityUpdate* state = aznew PrefabUndoEntityUpdate(AZStd::to_string(static_cast(entityId))); + state->SetParent(parentUndoBatch); + state->Capture(beforeState, afterState, entityId); + + state->Redo(); + } + + // Update the cache + m_prefabUndoCache.Store(entityId, AZStd::move(afterState)); + } + else + { + m_prefabUndoCache.PurgeCache(entityId); + } } - - // Update the cache - m_prefabUndoCache.Store(entityId, AZStd::move(afterState)); } - else - { - m_prefabUndoCache.PurgeCache(entityId); - } - } -} bool PrefabPublicHandler::IsInstanceContainerEntity(AZ::EntityId entityId) const { From 8f79379bc8c5132495f7b56e8e5c80d4d74bec4b Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 22 Apr 2021 16:45:20 -0700 Subject: [PATCH 7/8] Fixes as per Ram's review --- .../Entity/PrefabEditorEntityOwnershipInterface.h | 3 ++- .../Entity/PrefabEditorEntityOwnershipService.cpp | 8 +------- .../Entity/PrefabEditorEntityOwnershipService.h | 2 -- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h index 9dc3fc16f7..19c236f509 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h @@ -38,7 +38,8 @@ namespace AzToolsFramework AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0; //! Instantiate the prefab file provided. - //! /param entityToParentUnder The entity the newly created prefab instance is parented under. + //! /param filePath The filepath for the prefab file the instance should be created from. + //! /param instanceToParentUnder The instance the newly instantiated prefab instance is parented under. //! /return The optional reference to the prefab instance. virtual Prefab::InstanceOptionalReference InstantiatePrefab( AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 93e90efe96..4e74a1b020 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -53,10 +53,6 @@ namespace AzToolsFramework AZ_Assert(m_loaderInterface != nullptr, "Couldn't get prefab loader interface, it's a requirement for PrefabEntityOwnership system to work"); - m_instanceEntityMapperInterface = AZ::Interface::Get(); - AZ_Assert(m_instanceEntityMapperInterface != nullptr, - "Couldn't get instance entity mapper interface, it's a requirement for PrefabEntityOwnership system to work"); - m_rootInstance = AZStd::unique_ptr(m_prefabSystemComponent->CreatePrefab({}, {}, "NewLevel.prefab")); m_sliceOwnershipService.BusConnect(m_entityContextId); @@ -325,9 +321,7 @@ namespace AzToolsFramework } Prefab::Instance& addedInstance = instanceToParentUnder->get().AddInstance(AZStd::move(createdPrefabInstance)); - AZ::Entity* containerEntity = addedInstance.m_containerEntity.get(); - HandleEntitiesAdded({containerEntity}); - + HandleEntitiesAdded({addedInstance.m_containerEntity.get()}); return addedInstance; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h index 2c66c691b6..9c483e61c5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h @@ -25,7 +25,6 @@ namespace AzToolsFramework namespace Prefab { class Instance; - class InstanceEntityMapperInterface; class PrefabSystemComponentInterface; class PrefabLoaderInterface; } @@ -209,7 +208,6 @@ namespace AzToolsFramework AZStd::string m_rootPath; AZStd::unique_ptr m_rootInstance; - Prefab::InstanceEntityMapperInterface* m_instanceEntityMapperInterface; Prefab::PrefabSystemComponentInterface* m_prefabSystemComponent; Prefab::PrefabLoaderInterface* m_loaderInterface; AzFramework::EntityContextId m_entityContextId; From eae9d60c159090744e6370d18559b46ae3b2a63f Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 22 Apr 2021 23:36:29 -0700 Subject: [PATCH 8/8] Pass position Vector3 as const reference in InstantiatePrefab. --- .../AzToolsFramework/Prefab/PrefabPublicHandler.cpp | 2 +- .../AzToolsFramework/Prefab/PrefabPublicHandler.h | 2 +- .../AzToolsFramework/Prefab/PrefabPublicInterface.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 2ed40e748f..c3c784002e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -150,7 +150,7 @@ namespace AzToolsFramework } PrefabOperationResult PrefabPublicHandler::InstantiatePrefab( - AZStd::string_view filePath, AZ::EntityId parent, AZ::Vector3 position) + AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) { auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get(); if (!prefabEditorEntityOwnershipInterface) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index 19985bbf51..e83513dbff 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -45,7 +45,7 @@ namespace AzToolsFramework // PrefabPublicInterface... PrefabOperationResult CreatePrefab(const AZStd::vector& entityIds, AZ::IO::PathView filePath) override; - PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, AZ::Vector3 position) override; + PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override; PrefabOperationResult SavePrefab(AZ::IO::Path filePath) override; PrefabEntityResult CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h index 4e59729ab2..1a8da0dfe0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h @@ -58,7 +58,7 @@ namespace AzToolsFramework * @param position The position in world space the prefab should be instantiated in. * @return An outcome object; on failure, it comes with an error message detailing the cause of the error. */ - virtual PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, AZ::Vector3 position) = 0; + virtual PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) = 0; /** * Saves changes to prefab to disk.