Add Detach and Duplicate Prefab basic workflow auto test (#4506)
- Add a new automated test PrefabBasicWorkflow_CreateReparentAndDetachPrefab for verifying prefab detachment basic workflow. - Add a new automated test PrefabBasicWorkflow_CreateAndDuplicatePrefab for verifying prefab detachment basic workflow. - Fix a bug related to sets of entity ids in Reparent helper function .
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Math/Uuid.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
@@ -38,6 +40,13 @@ namespace AzToolsFramework
|
||||
AZ::Edit::SliceFlags::DontGatherReference);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->ConstantProperty(
|
||||
"EditorPrefabComponentTypeId", BehaviorConstant(AZ::Uuid(EditorPrefabComponent::EditorPrefabComponentTypeId)))
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorPrefabComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
|
||||
@@ -16,7 +16,9 @@ namespace AzToolsFramework
|
||||
class EditorPrefabComponent : public AzToolsFramework::Components::EditorComponentBase
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(EditorPrefabComponent, "{756E5F9C-3E08-4F8D-855C-A5AEEFB6FCDD}", EditorComponentBase);
|
||||
static constexpr const char* const EditorPrefabComponentTypeId = "{756E5F9C-3E08-4F8D-855C-A5AEEFB6FCDD}";
|
||||
|
||||
AZ_COMPONENT(EditorPrefabComponent, EditorPrefabComponentTypeId, EditorComponentBase);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
|
||||
|
||||
@@ -974,7 +974,7 @@ namespace AzToolsFramework
|
||||
return DeleteFromInstance(entityIds, true);
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::DuplicateEntitiesInInstance(const EntityIdList& entityIds)
|
||||
DuplicatePrefabResult PrefabPublicHandler::DuplicateEntitiesInInstance(const EntityIdList& entityIds)
|
||||
{
|
||||
if (entityIds.empty())
|
||||
{
|
||||
@@ -1021,6 +1021,7 @@ namespace AzToolsFramework
|
||||
|
||||
ScopedUndoBatch undoBatch("Duplicate Entities");
|
||||
|
||||
EntityIdList duplicatedEntityAndInstanceIds;
|
||||
{
|
||||
AZ_PROFILE_SCOPE(AzToolsFramework, "DuplicateEntitiesInInstance::UndoCaptureAndDuplicateEntities");
|
||||
|
||||
@@ -1033,7 +1034,7 @@ namespace AzToolsFramework
|
||||
|
||||
if (!retrieveEntitiesAndInstancesOutcome.IsSuccess())
|
||||
{
|
||||
return AZStd::move(retrieveEntitiesAndInstancesOutcome);
|
||||
return AZ::Failure(retrieveEntitiesAndInstancesOutcome.TakeError());
|
||||
}
|
||||
|
||||
// Take a snapshot of the instance DOM before we manipulate it
|
||||
@@ -1044,8 +1045,6 @@ namespace AzToolsFramework
|
||||
PrefabDom instanceDomAfter;
|
||||
instanceDomAfter.CopyFrom(instanceDomBefore, instanceDomAfter.GetAllocator());
|
||||
|
||||
EntityIdList duplicatedEntityAndInstanceIds;
|
||||
|
||||
// Duplicate any nested entities and instances as requested
|
||||
AZStd::unordered_map<InstanceAlias, Instance*> newInstanceAliasToOldInstanceMap;
|
||||
AZStd::unordered_map<EntityAlias, EntityAlias> duplicateEntityAliasMap;
|
||||
@@ -1114,7 +1113,7 @@ namespace AzToolsFramework
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, duplicatedEntityAndInstanceIds);
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
return AZ::Success(AZStd::move(duplicatedEntityAndInstanceIds));
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::DeleteFromInstance(const EntityIdList& entityIds, bool deleteDescendants)
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace AzToolsFramework
|
||||
|
||||
PrefabOperationResult DeleteEntitiesInInstance(const EntityIdList& entityIds) override;
|
||||
PrefabOperationResult DeleteEntitiesAndAllDescendantsInInstance(const EntityIdList& entityIds) override;
|
||||
PrefabOperationResult DuplicateEntitiesInInstance(const EntityIdList& entityIds) override;
|
||||
DuplicatePrefabResult DuplicateEntitiesInInstance(const EntityIdList& entityIds) override;
|
||||
|
||||
PrefabOperationResult DetachPrefab(const AZ::EntityId& containerEntityId) override;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
typedef AZ::Outcome<AZ::EntityId, AZStd::string> CreatePrefabResult;
|
||||
typedef AZ::Outcome<AZ::EntityId, AZStd::string> InstantiatePrefabResult;
|
||||
typedef AZ::Outcome<EntityIdList, AZStd::string> DuplicatePrefabResult;
|
||||
typedef AZ::Outcome<void, AZStd::string> PrefabOperationResult;
|
||||
typedef AZ::Outcome<bool, AZStd::string> PrefabRequestResult;
|
||||
typedef AZ::Outcome<AZ::EntityId, AZStd::string> PrefabEntityResult;
|
||||
@@ -160,14 +161,15 @@ namespace AzToolsFramework
|
||||
/**
|
||||
* Duplicates all entities in the owning instance. Bails if the entities don't all belong to the same instance.
|
||||
* @param entities The entities to duplicate.
|
||||
* @return An outcome object; on failure, it comes with an error message detailing the cause of the error.
|
||||
* @return An outcome object with a list of ids of target entities' duplicates if duplication succeeded;
|
||||
* on failure, it comes with an error message detailing the cause of the error.
|
||||
*/
|
||||
virtual PrefabOperationResult DuplicateEntitiesInInstance(const EntityIdList& entityIds) = 0;
|
||||
virtual DuplicatePrefabResult DuplicateEntitiesInInstance(const EntityIdList& entityIds) = 0;
|
||||
|
||||
/**
|
||||
* If the entity id is a container entity id, detaches the prefab instance corresponding to it. This includes converting
|
||||
* the container entity into a regular entity and putting it under the parent prefab, removing the link between this
|
||||
* instance and the parent, removing links between this instance and it's nested instances, adding entities directly
|
||||
* instance and the parent, removing links between this instance and its nested instances, and adding entities directly
|
||||
* owned by this instance under the parent instance.
|
||||
* Bails if the entity is not a container entity or belongs to the level prefab instance.
|
||||
* @param containerEntityId The container entity id of the instance to detach.
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
using CreatePrefabResult = AZ::Outcome<AZ::EntityId, AZStd::string>;
|
||||
using InstantiatePrefabResult = AZ::Outcome<AZ::EntityId, AZStd::string>;
|
||||
using DuplicatePrefabResult = AZ::Outcome<EntityIdList, AZStd::string>;
|
||||
using PrefabOperationResult = AZ::Outcome<void, AZStd::string>;
|
||||
|
||||
/**
|
||||
@@ -69,6 +70,29 @@ namespace AzToolsFramework
|
||||
* Return an outcome object; on failure, it comes with an error message detailing the cause of the error.
|
||||
*/
|
||||
virtual PrefabOperationResult DeleteEntitiesAndAllDescendantsInInstance(const EntityIdList& entityIds) = 0;
|
||||
|
||||
/**
|
||||
* If the entity id is a container entity id, detaches the prefab instance corresponding to it. This includes converting
|
||||
* the container entity into a regular entity and putting it under the parent prefab, removing the link between this
|
||||
* instance and the parent, removing links between this instance and its nested instances, and adding entities directly
|
||||
* owned by this instance under the parent instance.
|
||||
* Bails if the entity is not a container entity or belongs to the level prefab instance.
|
||||
* Return an outcome object; on failure, it comes with an error message detailing the cause of the error.
|
||||
*/
|
||||
virtual PrefabOperationResult DetachPrefab(const AZ::EntityId& containerEntityId) = 0;
|
||||
|
||||
/**
|
||||
* Duplicates all entities in the owning instance. Bails if the entities don't all belong to the same instance.
|
||||
* Return an outcome object with a list of ids of given entities' duplicates if duplication succeeded;
|
||||
* on failure, it comes with an error message detailing the cause of the error.
|
||||
*/
|
||||
virtual DuplicatePrefabResult DuplicateEntitiesInInstance(const EntityIdList& entityIds) = 0;
|
||||
|
||||
/**
|
||||
* Get the file path to the prefab file for the prefab instance owning the entity provided.
|
||||
* Returns the path to the prefab, or an empty path if the entity is owned by the level.
|
||||
*/
|
||||
virtual AZStd::string GetOwningInstancePrefabPath(AZ::EntityId entityId) const = 0;
|
||||
};
|
||||
|
||||
using PrefabPublicRequestBus = AZ::EBus<PrefabPublicRequests>;
|
||||
|
||||
+17
@@ -28,6 +28,9 @@ namespace AzToolsFramework
|
||||
->Event("CreatePrefabInMemory", &PrefabPublicRequests::CreatePrefabInMemory)
|
||||
->Event("InstantiatePrefab", &PrefabPublicRequests::InstantiatePrefab)
|
||||
->Event("DeleteEntitiesAndAllDescendantsInInstance", &PrefabPublicRequests::DeleteEntitiesAndAllDescendantsInInstance)
|
||||
->Event("DetachPrefab", &PrefabPublicRequests::DetachPrefab)
|
||||
->Event("DuplicateEntitiesInInstance", &PrefabPublicRequests::DuplicateEntitiesInInstance)
|
||||
->Event("GetOwningInstancePrefabPath", &PrefabPublicRequests::GetOwningInstancePrefabPath)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -62,5 +65,19 @@ namespace AzToolsFramework
|
||||
return m_prefabPublicInterface->DeleteEntitiesAndAllDescendantsInInstance(entityIds);
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicRequestHandler::DetachPrefab(const AZ::EntityId& containerEntityId)
|
||||
{
|
||||
return m_prefabPublicInterface->DetachPrefab(containerEntityId);
|
||||
}
|
||||
|
||||
DuplicatePrefabResult PrefabPublicRequestHandler::DuplicateEntitiesInInstance(const EntityIdList& entityIds)
|
||||
{
|
||||
return m_prefabPublicInterface->DuplicateEntitiesInInstance(entityIds);
|
||||
}
|
||||
|
||||
AZStd::string PrefabPublicRequestHandler::GetOwningInstancePrefabPath(AZ::EntityId entityId) const
|
||||
{
|
||||
return m_prefabPublicInterface->GetOwningInstancePrefabPath(entityId).Native();
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -34,6 +34,9 @@ namespace AzToolsFramework
|
||||
CreatePrefabResult CreatePrefabInMemory(const EntityIdList& entityIds, AZStd::string_view filePath) override;
|
||||
InstantiatePrefabResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override;
|
||||
PrefabOperationResult DeleteEntitiesAndAllDescendantsInInstance(const EntityIdList& entityIds) override;
|
||||
PrefabOperationResult DetachPrefab(const AZ::EntityId& containerEntityId) override;
|
||||
DuplicatePrefabResult DuplicateEntitiesInInstance(const EntityIdList& entityIds) override;
|
||||
AZStd::string GetOwningInstancePrefabPath(AZ::EntityId entityId) const override;
|
||||
|
||||
private:
|
||||
PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
//PrefabInstanceUndo
|
||||
PrefabUndoInstance::PrefabUndoInstance(const AZStd::string& undoOperationName, const bool useImmediatePropagation)
|
||||
PrefabUndoInstance::PrefabUndoInstance(const AZStd::string& undoOperationName, bool useImmediatePropagation)
|
||||
: PrefabUndoBase(undoOperationName)
|
||||
{
|
||||
m_useImmediatePropagation = useImmediatePropagation;
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace AzToolsFramework
|
||||
: public PrefabUndoBase
|
||||
{
|
||||
public:
|
||||
explicit PrefabUndoInstance(const AZStd::string& undoOperationName, const bool useImmediatePropagation = true);
|
||||
explicit PrefabUndoInstance(const AZStd::string& undoOperationName, bool useImmediatePropagation = true);
|
||||
|
||||
void Capture(
|
||||
const PrefabDom& initialState,
|
||||
|
||||
Reference in New Issue
Block a user