Instantiate Prefab
This commit is contained in:
+8
-1
@@ -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<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& 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;
|
||||
|
||||
+27
@@ -19,6 +19,7 @@
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h>
|
||||
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabLoader.h>
|
||||
@@ -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<Prefab::InstanceEntityMapperInterface>::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<Prefab::Instance>(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<Prefab::Instance> 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.");
|
||||
|
||||
+5
@@ -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<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& 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<Prefab::Instance> m_rootInstance;
|
||||
Prefab::InstanceEntityMapperInterface* m_instanceEntityMapperInterface;
|
||||
Prefab::PrefabSystemComponentInterface* m_prefabSystemComponent;
|
||||
Prefab::PrefabLoaderInterface* m_loaderInterface;
|
||||
AzFramework::EntityContextId m_entityContextId;
|
||||
|
||||
@@ -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<PrefabEditorEntityOwnershipInterface>::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<AZ::EntityId>& 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<PrefabSystemComponentInterface>::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<AZ::u64>(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<AZ::u64>(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<AZ::u64>(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
|
||||
{
|
||||
|
||||
@@ -260,6 +260,29 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<Instance> 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<Instance> PrefabSystemComponent::InstantiatePrefab(const TemplateId& templateId)
|
||||
{
|
||||
TemplateReference instantiatingTemplate = FindTemplate(templateId);
|
||||
|
||||
@@ -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<Instance> 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<Instance> InstantiatePrefab(const TemplateId& templateId) override;
|
||||
|
||||
+1
@@ -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<Instance> InstantiatePrefab(AZ::IO::PathView filePath) = 0;
|
||||
virtual AZStd::unique_ptr<Instance> InstantiatePrefab(const TemplateId& templateId) = 0;
|
||||
virtual AZStd::unique_ptr<Instance> CreatePrefab(const AZStd::vector<AZ::Entity*>& entities,
|
||||
AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume, AZ::IO::PathView filePath,
|
||||
|
||||
Reference in New Issue
Block a user