Merge branch 'main' into Spawnable/ProductDependency
This commit is contained in:
@@ -11,8 +11,10 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetJsonSerializer.h>
|
||||
#include <AzCore/JSON/prettywriter.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
@@ -115,6 +117,48 @@ namespace AzToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
Instance& instance, const PrefabDom& prefabDom, AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets, LoadInstanceFlags flags)
|
||||
{
|
||||
// When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will
|
||||
// be released and reloaded once the entities are built up again. By suspending asset release temporarily the asset reload
|
||||
// is avoided.
|
||||
AZ::Data::AssetManager::Instance().SuspendAssetRelease();
|
||||
|
||||
InstanceEntityIdMapper entityIdMapper;
|
||||
entityIdMapper.SetLoadingInstance(instance);
|
||||
if ((flags & LoadInstanceFlags::AssignRandomEntityId) == LoadInstanceFlags::AssignRandomEntityId)
|
||||
{
|
||||
entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random);
|
||||
}
|
||||
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
// The InstanceEntityIdMapper is registered twice because it's used in several places during deserialization where one is
|
||||
// specific for the InstanceEntityIdMapper and once for the generic JsonEntityIdMapper. Because the Json Serializer's meta
|
||||
// data has strict typing and doesn't look for inheritance both have to be explicitly added so they're found both locations.
|
||||
settings.m_metadata.Add(static_cast<AZ::JsonEntityIdSerializer::JsonEntityIdMapper*>(&entityIdMapper));
|
||||
settings.m_metadata.Add(&entityIdMapper);
|
||||
settings.m_metadata.Create<AZ::Data::SerializedAssetTracker>();
|
||||
|
||||
AZ::JsonSerializationResult::ResultCode result =
|
||||
AZ::JsonSerialization::Load(instance, prefabDom, settings);
|
||||
|
||||
AZ::Data::AssetManager::Instance().ResumeAssetRelease();
|
||||
|
||||
if (result.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
|
||||
{
|
||||
AZ_Error("Prefab", false,
|
||||
"Failed to de-serialize Prefab Instance from Prefab DOM. "
|
||||
"Unable to proceed.");
|
||||
|
||||
return false;
|
||||
}
|
||||
AZ::Data::SerializedAssetTracker* assetTracker = settings.m_metadata.Find<AZ::Data::SerializedAssetTracker>();
|
||||
|
||||
referencedAssets = AZStd::move(assetTracker->GetTrackedAssets());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadInstanceFlags flags)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomTypes.h>
|
||||
|
||||
@@ -42,7 +43,7 @@ namespace AzToolsFramework
|
||||
/**
|
||||
* Stores a valid Prefab Instance within a Prefab Dom. Useful for generating Templates
|
||||
* @param instance The instance to store
|
||||
* @param prefabDom the prefabDom that will be used to store the Instance data
|
||||
* @param prefabDom The prefabDom that will be used to store the Instance data
|
||||
* @return bool on whether the operation succeeded
|
||||
*/
|
||||
bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom);
|
||||
@@ -60,20 +61,32 @@ namespace AzToolsFramework
|
||||
/**
|
||||
* Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances.
|
||||
* @param instance The Instance to load.
|
||||
* @param prefabDom the prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers whether to clear containers in Instance while loading.
|
||||
* @param prefabDom The prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers Whether to clear containers in Instance while loading.
|
||||
* @return bool on whether the operation succeeded.
|
||||
*/
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
Instance& instance, const PrefabDom& prefabDom, LoadInstanceFlags flags = LoadInstanceFlags::None);
|
||||
|
||||
/**
|
||||
* Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances.
|
||||
* @param instance The Instance to load.
|
||||
* @param referencedAssets AZ::Assets discovered during json load are added to this list
|
||||
* @param prefabDom The prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers Whether to clear containers in Instance while loading.
|
||||
* @return bool on whether the operation succeeded.
|
||||
*/
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
Instance& instance, const PrefabDom& prefabDom, AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets,
|
||||
LoadInstanceFlags flags = LoadInstanceFlags::None);
|
||||
|
||||
/**
|
||||
* Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances.
|
||||
* @param instance The Instance to load.
|
||||
* @param newlyAddedEntities The new instances added during deserializing the instance. These are the entities found
|
||||
* in the prefabDom.
|
||||
* @param prefabDom the prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers whether to clear containers in Instance while loading.
|
||||
* @param prefabDom The prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers Whether to clear containers in Instance while loading.
|
||||
* @return bool on whether the operation succeeded.
|
||||
*/
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
|
||||
@@ -89,16 +89,14 @@ 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
|
||||
// target templates of the other instances.
|
||||
for (auto& nestedInstance : instances)
|
||||
{
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
nestedInstance->GetTemplateId(), commonRootEntityOwningInstance->get().GetTemplateId(),
|
||||
nestedInstance->GetInstanceAlias(), nestedInstance->GetLinkId(), undoBatch.GetUndoBatch());
|
||||
RemoveLink(nestedInstance, commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
@@ -142,9 +140,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())
|
||||
{
|
||||
m_prefabUndoCache.UpdateCache(topLevelEntityId);
|
||||
undoBatch.MarkEntityDirty(topLevelEntityId);
|
||||
AZ::TransformBus::Event(topLevelEntityId, &AZ::TransformBus::Events::SetParent, containerEntityId);
|
||||
}
|
||||
}
|
||||
|
||||
// Select Container Entity
|
||||
@@ -184,6 +186,22 @@ namespace AzToolsFramework
|
||||
instanceToParentUnder = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
||||
parent = instanceToParentUnder->get().GetContainerEntityId();
|
||||
}
|
||||
|
||||
//Detect whether this instantiation would produce a cyclical dependency
|
||||
auto relativePath = m_prefabLoaderInterface->GetRelativePathToProject(filePath);
|
||||
Prefab::TemplateId templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(relativePath);
|
||||
|
||||
// If the template isn't currently loaded, there's no way for it to be in the hierarchy so we just skip the check.
|
||||
if (templateId != Prefab::InvalidTemplateId && IsPrefabInInstanceAncestorHierarchy(templateId, instanceToParentUnder->get()))
|
||||
{
|
||||
return AZ::Failure(
|
||||
AZStd::string::format(
|
||||
"Instantiate Prefab operation aborted - Cyclical dependency detected\n(%s depends on %s).",
|
||||
relativePath.Native().c_str(),
|
||||
instanceToParentUnder->get().GetTemplateSourcePath().Native().c_str()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// Initialize Undo Batch object
|
||||
@@ -194,7 +212,7 @@ namespace AzToolsFramework
|
||||
instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get());
|
||||
|
||||
// Instantiate the Prefab
|
||||
auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(filePath, instanceToParentUnder);
|
||||
auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(relativePath, instanceToParentUnder);
|
||||
|
||||
if (!instanceToCreate)
|
||||
{
|
||||
@@ -223,6 +241,21 @@ namespace AzToolsFramework
|
||||
// Retrieve entityList from entityIds
|
||||
inputEntityList = EntityIdListToEntityList(entityIds);
|
||||
|
||||
// Remove Level Container Entity if it's part of the list
|
||||
AZ::EntityId levelEntityId = GetLevelInstanceContainerEntityId();
|
||||
if (levelEntityId.IsValid())
|
||||
{
|
||||
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
|
||||
bool entitiesHaveCommonRoot = false;
|
||||
|
||||
@@ -238,17 +271,29 @@ namespace AzToolsFramework
|
||||
|
||||
// Retrieve the owning instance of the common root entity, which will be our new instance's parent instance.
|
||||
commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
|
||||
if (!commonRootEntityOwningInstance)
|
||||
{
|
||||
AZ_Assert(
|
||||
false,
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided"));
|
||||
}
|
||||
AZ_Assert(
|
||||
commonRootEntityOwningInstance.has_value(),
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
bool PrefabPublicHandler::IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance)
|
||||
{
|
||||
InstanceOptionalConstReference currentInstance = instance;
|
||||
|
||||
while (currentInstance.has_value())
|
||||
{
|
||||
if (currentInstance->get().GetTemplateId() == prefabTemplateId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
currentInstance = currentInstance->get().GetParentInstance();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::CreateLink(
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId)
|
||||
@@ -287,6 +332,34 @@ namespace AzToolsFramework
|
||||
m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::RemoveLink(
|
||||
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
LinkReference nestedInstanceLink = m_prefabSystemComponentInterface->FindLink(sourceInstance->GetLinkId());
|
||||
AZ_Assert(
|
||||
nestedInstanceLink.has_value(),
|
||||
"A valid link was not found for one of the instances provided as input for the CreatePrefab operation.");
|
||||
|
||||
PrefabDomReference nestedInstanceLinkDom = nestedInstanceLink->get().GetLinkDom();
|
||||
AZ_Assert(
|
||||
nestedInstanceLinkDom.has_value(),
|
||||
"A valid DOM was not found for the link corresponding to one of the instances provided as input for the "
|
||||
"CreatePrefab operation.");
|
||||
|
||||
PrefabDomValueReference nestedInstanceLinkPatches =
|
||||
PrefabDomUtils::FindPrefabDomValue(nestedInstanceLinkDom->get(), PrefabDomUtils::PatchesName);
|
||||
AZ_Assert(
|
||||
nestedInstanceLinkPatches.has_value(),
|
||||
"A valid DOM for patches was not found for the link corresponding to one of the instances provided as input for the "
|
||||
"CreatePrefab operation.");
|
||||
|
||||
PrefabDom patchesCopyForUndoSupport;
|
||||
patchesCopyForUndoSupport.CopyFrom(nestedInstanceLinkPatches->get(), patchesCopyForUndoSupport.GetAllocator());
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
sourceInstance->GetTemplateId(), targetTemplateId, sourceInstance->GetInstanceAlias(), sourceInstance->GetLinkId(),
|
||||
patchesCopyForUndoSupport, undoBatch);
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath)
|
||||
{
|
||||
auto templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(filePath.c_str());
|
||||
@@ -753,6 +826,11 @@ namespace AzToolsFramework
|
||||
const EntityList& inputEntities, Instance& commonRootEntityOwningInstance,
|
||||
EntityList& outEntities, AZStd::vector<AZStd::unique_ptr<Instance>>& outInstances) const
|
||||
{
|
||||
if (inputEntities.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AZStd::queue<AZ::Entity*> entityQueue;
|
||||
|
||||
for (auto inputEntity : inputEntities)
|
||||
@@ -840,7 +918,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
|
||||
|
||||
@@ -82,6 +82,16 @@ namespace AzToolsFramework
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId);
|
||||
|
||||
/**
|
||||
* Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId.
|
||||
*
|
||||
* \param sourceInstance The instance corresponding to the source template of the link to be removed.
|
||||
* \param targetTemplateId The id of the target template of the link to be removed.
|
||||
* \param undoBatch The undo batch to set as parent for this remove link action.
|
||||
*/
|
||||
void RemoveLink(
|
||||
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch);
|
||||
|
||||
/**
|
||||
* Given a list of entityIds, finds the prefab instance that owns the common root entity of the entityIds.
|
||||
*
|
||||
@@ -96,6 +106,14 @@ namespace AzToolsFramework
|
||||
const AZStd::vector<AZ::EntityId>& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
|
||||
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance);
|
||||
|
||||
/* Detects whether an instance of prefabTemplateId is present in the hierarchy of ancestors of instance.
|
||||
*
|
||||
* \param prefabTemplateId The template id to test for
|
||||
* \param instance The instance whose ancestor hierarchy prefabTemplateId will be tested against.
|
||||
* \return true if an instance of the template of id prefabTemplateId could be found in the ancestor hierarchy of instance, false otherwise.
|
||||
*/
|
||||
bool IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance);
|
||||
|
||||
static Instance* GetParentInstance(Instance* instance);
|
||||
static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant);
|
||||
static void GenerateContainerEntityTransform(const EntityList& topLevelEntities, AZ::Vector3& translation, AZ::Quaternion& rotation);
|
||||
|
||||
@@ -663,8 +663,9 @@ namespace AzToolsFramework
|
||||
newLink.SetSourceTemplateId(linkSourceId);
|
||||
newLink.SetInstanceName(instanceAlias.c_str());
|
||||
newLink.GetLinkDom().SetObject();
|
||||
newLink.GetLinkDom().AddMember(rapidjson::StringRef(PrefabDomUtils::SourceName),
|
||||
rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()), newLink.GetLinkDom().GetAllocator());
|
||||
newLink.GetLinkDom().AddMember(
|
||||
rapidjson::StringRef(PrefabDomUtils::SourceName), rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()),
|
||||
newLink.GetLinkDom().GetAllocator());
|
||||
|
||||
if (linkPatch && linkPatch->get().IsArray() && !(linkPatch->get().Empty()))
|
||||
{
|
||||
@@ -720,6 +721,8 @@ namespace AzToolsFramework
|
||||
|
||||
TemplateId PrefabSystemComponent::GetTemplateIdFromFilePath(AZ::IO::PathView filePath) const
|
||||
{
|
||||
AZ_Assert(!filePath.IsAbsolute(), "Prefab - GetTemplateIdFromFilePath was passed an absolute path. Prefabs use paths relative to the project folder.");
|
||||
|
||||
auto found = m_templateFilePathToIdMap.find(filePath);
|
||||
if (found != m_templateFilePathToIdMap.end())
|
||||
{
|
||||
@@ -770,8 +773,8 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
Template& targetTemplate = targetTemplateReference->get();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace AzToolsFramework
|
||||
, m_sourceId(InvalidTemplateId)
|
||||
, m_instanceAlias("")
|
||||
, m_linkId(InvalidLinkId)
|
||||
, m_linkDom(PrefabDom())
|
||||
, m_linkPatches(PrefabDom())
|
||||
, m_linkStatus(LinkStatus::LINKSTATUS)
|
||||
{
|
||||
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
@@ -124,7 +124,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkDom,
|
||||
PrefabDomReference linkPatches,
|
||||
const LinkId linkId)
|
||||
{
|
||||
m_targetId = targetId;
|
||||
@@ -132,9 +132,9 @@ namespace AzToolsFramework
|
||||
m_instanceAlias = instanceAlias;
|
||||
m_linkId = linkId;
|
||||
|
||||
if (linkDom.has_value())
|
||||
if (linkPatches.has_value())
|
||||
{
|
||||
m_linkDom = AZStd::move(linkDom->get());
|
||||
m_linkPatches = AZStd::move(linkPatches->get());
|
||||
}
|
||||
|
||||
//if linkId is invalid, set as ADD
|
||||
@@ -193,7 +193,7 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabUndoInstanceLink::AddLink()
|
||||
{
|
||||
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkDom, m_linkId);
|
||||
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkPatches, m_linkId);
|
||||
}
|
||||
|
||||
void PrefabUndoInstanceLink::RemoveLink()
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkDom = PrefabDomReference(),
|
||||
PrefabDomReference linkPatches = PrefabDomReference(),
|
||||
const LinkId linkId = InvalidLinkId);
|
||||
|
||||
void Undo() override;
|
||||
@@ -120,7 +120,7 @@ namespace AzToolsFramework
|
||||
InstanceAlias m_instanceAlias;
|
||||
|
||||
LinkId m_linkId;
|
||||
PrefabDom m_linkDom; //data for delete/update
|
||||
PrefabDom m_linkPatches; //data for delete/update
|
||||
LinkStatus m_linkStatus;
|
||||
|
||||
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
|
||||
|
||||
@@ -46,13 +46,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch)
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link");
|
||||
PrefabDom emptyLinkDom;
|
||||
linkRemoveUndo->Capture(
|
||||
targetTemplateId, sourceTemplateId, instanceAlias, emptyLinkDom, linkId);
|
||||
linkRemoveUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, linkPatches, linkId);
|
||||
linkRemoveUndo->SetParent(undoBatch);
|
||||
linkRemoveUndo->Redo();
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace AzToolsFramework
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
|
||||
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch);
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch);
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch);
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
AZStd::move(uniqueName), context.GetSourceUuid(), AZStd::move(serializer));
|
||||
AZ_Assert(spawnable, "Failed to create a new spawnable.");
|
||||
|
||||
bool result = SpawnableUtils::CreateSpawnable(*spawnable, prefab);
|
||||
bool result = SpawnableUtils::CreateSpawnable(*spawnable, prefab, object.GetReferencedAssets());
|
||||
if (result)
|
||||
{
|
||||
AzFramework::Spawnable::EntityList& entities = spawnable->GetEntities();
|
||||
|
||||
+10
@@ -56,6 +56,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
return *m_asset;
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& ProcessedObjectStore::GetReferencedAssets()
|
||||
{
|
||||
return m_referencedAssets;
|
||||
}
|
||||
|
||||
const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& ProcessedObjectStore::GetReferencedAssets() const
|
||||
{
|
||||
return m_referencedAssets;
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<AZ::Data::AssetData> ProcessedObjectStore::ReleaseAsset()
|
||||
{
|
||||
return AZStd::move(m_asset);
|
||||
|
||||
+5
@@ -48,6 +48,10 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
AZ::Data::AssetData& GetAsset();
|
||||
AZStd::unique_ptr<AZ::Data::AssetData> ReleaseAsset();
|
||||
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& GetReferencedAssets();
|
||||
const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& GetReferencedAssets() const;
|
||||
|
||||
|
||||
const AZStd::string& GetId() const;
|
||||
|
||||
private:
|
||||
@@ -55,6 +59,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
SerializerFunction m_assetSerializer;
|
||||
AZStd::unique_ptr<AZ::Data::AssetData> m_asset;
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>> m_referencedAssets;
|
||||
AZStd::string m_uniqueId;
|
||||
};
|
||||
|
||||
|
||||
+9
-2
@@ -28,16 +28,23 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
AzFramework::Spawnable CreateSpawnable(const PrefabDom& prefabDom)
|
||||
{
|
||||
AzFramework::Spawnable spawnable;
|
||||
[[maybe_unused]] bool result = CreateSpawnable(spawnable, prefabDom);
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>> referencedAssets;
|
||||
[[maybe_unused]] bool result = CreateSpawnable(spawnable, prefabDom, referencedAssets);
|
||||
AZ_Assert(result,
|
||||
"Failed to Load Prefab Instance from given Prefab DOM while Spawnable creation.");
|
||||
return spawnable;
|
||||
}
|
||||
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom)
|
||||
{
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>> referencedAssets;
|
||||
return CreateSpawnable(spawnable, prefabDom, referencedAssets);
|
||||
}
|
||||
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets)
|
||||
{
|
||||
Instance instance;
|
||||
if (Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(instance, prefabDom,
|
||||
if (Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(instance, prefabDom, referencedAssets,
|
||||
Prefab::PrefabDomUtils::LoadInstanceFlags::AssignRandomEntityId)) // Always assign random entity ids because the spawnable is
|
||||
// going to be used to create clones of the entities.
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
{
|
||||
AzFramework::Spawnable CreateSpawnable(const PrefabDom& prefabDom);
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom);
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets);
|
||||
|
||||
void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable);
|
||||
} // namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
|
||||
Reference in New Issue
Block a user