diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h index c8a245af68..c5cdbbf331 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -216,16 +217,14 @@ namespace AZ /** * Setting for each reference (Asset) to control loading of referenced assets during serialization. */ - enum class AssetLoadBehavior : u8 - { - PreLoad = 0, ///< Serializer will "Pre load" dependencies, asset containers may load in parallel but will not signal AssetReady - QueueLoad = 1, ///< Serializer will queue an asynchronous load of the referenced asset and return the object to the user. User code should use the \ref AZ::Data::AssetBus to monitor for when it's ready. - NoLoad = 2, ///< Serializer will load reference information, but asset loading will be left to the user. User code should call Asset::QueueLoad and use the \ref AZ::Data::AssetBus to monitor for when it's ready. - ///< AssetContainers will skip NoLoad dependencies - + AZ_ENUM_WITH_UNDERLYING_TYPE(AssetLoadBehavior, u8, + (PreLoad, 0), ///< Serializer will "Pre load" dependencies, asset containers may load in parallel but will not signal AssetReady + (QueueLoad, 1), ///< Serializer will queue an asynchronous load of the referenced asset and return the object to the user. User code should use the \ref AZ::Data::AssetBus to monitor for when it's ready. + (NoLoad, 2), ///< Serializer will load reference information, but asset loading will be left to the user. User code should call Asset::QueueLoad and use the \ref AZ::Data::AssetBus to monitor for when it's ready. + ///< AssetContainers will skip NoLoad dependencies Count, - Default = QueueLoad, - }; + (Default, QueueLoad) + ); struct AssetFilterInfo { @@ -1222,6 +1221,7 @@ namespace AZ } // namespace ProductDependencyInfo } // namespace Data + AZ_TYPE_INFO_SPECIALIZE(Data::AssetLoadBehavior, "{DAF9ECED-FEF3-4D7A-A220-8CFD6A5E6DA1}"); AZ_TYPE_INFO_TEMPLATE_WITH_NAME(AZ::Data::Asset, "Asset", "{C891BF19-B60C-45E2-BFD0-027D15DDC939}", AZ_TYPE_INFO_CLASS); } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp index 767dadedf8..555eedf034 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp @@ -70,6 +70,17 @@ namespace AZ } } + { + const AZ::Data::AssetLoadBehavior autoLoadBehavior = instance->GetAutoLoadBehavior(); + const AZ::Data::AssetLoadBehavior defaultAutoLoadBehavior = defaultInstance ? + defaultInstance->GetAutoLoadBehavior() : AZ::Data::AssetLoadBehavior::Default; + + result.Combine( + ContinueStoringToJsonObjectField(outputValue, "loadBehavior", + &autoLoadBehavior, &defaultAutoLoadBehavior, + azrtti_typeid(), context)); + } + { ScopedContextPath subPathHint(context, "m_assetHint"); const AZStd::string* hint = &instance->GetHint(); @@ -100,14 +111,28 @@ namespace AZ AssetId id; JSR::ResultCode result(JSR::Tasks::ReadField); + SerializedAssetTracker* assetTracker = + context.GetMetadata().Find(); + + { + Data::AssetLoadBehavior loadBehavior = instance->GetAutoLoadBehavior(); + + result = + ContinueLoadingFromJsonObjectField(&loadBehavior, + azrtti_typeid(), + inputValue, "loadBehavior", context); + + instance->SetAutoLoadBehavior(loadBehavior); + } + auto it = inputValue.FindMember("assetId"); if (it != inputValue.MemberEnd()) { ScopedContextPath subPath(context, "assetId"); - result = ContinueLoading(&id, azrtti_typeid(), it->value, context); + result.Combine(ContinueLoading(&id, azrtti_typeid(), it->value, context)); if (!id.m_guid.IsNull()) { - *instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), AssetLoadBehavior::NoLoad); + *instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), instance->GetAutoLoadBehavior()); result.Combine(context.Report(result, "Successfully created Asset with id.")); @@ -142,6 +167,11 @@ namespace AZ "The asset hint is missing for Asset, so it will be left empty.")); } + if (assetTracker) + { + assetTracker->AddAsset(*instance); + } + bool success = result.GetOutcome() <= JSR::Outcomes::PartialSkip; bool defaulted = result.GetOutcome() == JSR::Outcomes::DefaultsUsed || result.GetOutcome() == JSR::Outcomes::PartialDefaults; AZStd::string_view message = @@ -150,5 +180,20 @@ namespace AZ "Not enough information was available to create an instance of Asset or data was corrupted."; return context.Report(result, message); } + + void SerializedAssetTracker::AddAsset(Asset& asset) + { + m_serializedAssets.emplace_back(asset); + } + + const AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() const + { + return m_serializedAssets; + } + + AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() + { + return m_serializedAssets; + } } // namespace Data } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h index 3d5271035c..780066cd42 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h @@ -13,6 +13,7 @@ #pragma once #include +#include #include namespace AZ @@ -37,5 +38,18 @@ namespace AZ private: JsonSerializationResult::Result LoadAsset(void* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context); }; + + class SerializedAssetTracker final + { + public: + AZ_RTTI(SerializedAssetTracker, "{1E067091-8C0A-44B1-A455-6E97663F6963}"); + + void AddAsset(Asset& asset); + AZStd::vector>& GetTrackedAssets(); + const AZStd::vector>& GetTrackedAssets() const; + + private: + AZStd::vector> m_serializedAssets; + }; } // namespace Data } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp index d861614309..1075c6a931 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -24,6 +24,11 @@ namespace AZ { + namespace Data + { + AZ_ENUM_DEFINE_REFLECT_UTILITIES(AssetLoadBehavior); + } + //========================================================================= // AssetDatabaseComponent // [6/25/2012] @@ -99,6 +104,8 @@ namespace AZ if (SerializeContext* serializeContext = azrtti_cast(context)) { + AZ::Data::AssetLoadBehaviorReflect(*serializeContext); + serializeContext->RegisterGenericType>(); serializeContext->Class() diff --git a/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h b/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h index e5bc76cd19..6806232337 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h +++ b/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h @@ -14,8 +14,6 @@ #include -#include - #include #include diff --git a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp index e44f77b119..3e4ddac3af 100644 --- a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp @@ -135,6 +135,7 @@ namespace JsonSerializationTests auto instance = AZStd::make_shared(); instance->Create(id, false); instance->SetHint("TestFile"); + instance->SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad); return instance; } @@ -158,6 +159,7 @@ namespace JsonSerializationTests "guid": "{BBEAC89F-8BAD-4A9D-BF6E-D0DF84A8DFD6}", "subId": 1 }, + "loadBehavior": "PreLoad", "assetHint": "TestFile" })"; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 81233069a9..6b6f1475bb 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -342,6 +343,65 @@ namespace AzToolsFramework m_validateEntitiesCallback = AZStd::move(validateEntitiesCallback); } + void PrefabEditorEntityOwnershipService::LoadReferencedAssets(AZStd::vector>& referencedAssets) + { + // Start our loads on all assets by calling GetAsset from the AssetManager + for (AZ::Data::Asset& asset : referencedAssets) + { + if (!asset.GetId().IsValid()) + { + AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode"); + continue; + } + + const AZ::Data::AssetLoadBehavior loadBehavior = asset.GetAutoLoadBehavior(); + + if (loadBehavior == AZ::Data::AssetLoadBehavior::NoLoad) + { + continue; + } + + AZ::Data::AssetId assetId = asset.GetId(); + AZ::Data::AssetType assetType = asset.GetType(); + + asset = AZ::Data::AssetManager::Instance().GetAsset(assetId, assetType, loadBehavior); + + if (!asset.GetId().IsValid()) + { + AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode"); + continue; + } + } + + // For all Preload assets we block until they're ready + // We do this as a seperate pass so that we don't interrupt queuing up all other asset loads + for (AZ::Data::Asset& asset : referencedAssets) + { + if (!asset.GetId().IsValid()) + { + AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode"); + continue; + } + + const AZ::Data::AssetLoadBehavior loadBehavior = asset.GetAutoLoadBehavior(); + + if (loadBehavior != AZ::Data::AssetLoadBehavior::PreLoad) + { + continue; + } + + asset.BlockUntilLoadComplete(); + + if (asset.IsError()) + { + AZ_Error("Prefab", false, "Asset with id %s failed to preload while entering game mode", + asset.GetId().ToString().c_str()); + + continue; + } + } + } + void PrefabEditorEntityOwnershipService::StartPlayInEditor() { // This is a workaround until the replacement for GameEntityContext is done @@ -381,16 +441,21 @@ namespace AzToolsFramework rootSpawnableIndex = m_playInEditorData.m_assets.size(); } + LoadReferencedAssets(product.GetReferencedAssets()); + AZ::Data::AssetInfo info; info.m_assetId = product.GetAsset().GetId(); info.m_assetType = product.GetAssetType(); info.m_relativePath = product.GetId(); AZ::Data::AssetCatalogRequestBus::Broadcast( - &AZ::Data::AssetCatalogRequestBus::Events::RegisterAsset, product.GetAsset().GetId(), info); + &AZ::Data::AssetCatalogRequestBus::Events::RegisterAsset, info.m_assetId, info); m_playInEditorData.m_assets.emplace_back(product.ReleaseAsset().release(), AZ::Data::AssetLoadBehavior::Default); } + // make sure that PRE_NOTIFY assets get their notify before we activate, so that we can preserve the order of + // (load asset) -> (notify) -> (init) -> (activate) + AZ::Data::AssetManager::Instance().DispatchEvents(); if (rootSpawnableIndex != NoRootSpawnable) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h index 9c483e61c5..48e07df091 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h @@ -199,6 +199,8 @@ namespace AzToolsFramework void OnEntityRemoved(AZ::EntityId entityId); + void LoadReferencedAssets(AZStd::vector>& referencedAssets); + OnEntitiesAddedCallback m_entitiesAddedCallback; OnEntitiesRemovedCallback m_entitiesRemovedCallback; ValidateEntitiesCallback m_validateEntitiesCallback; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index d53aeaa241..0bffd26be0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -11,8 +11,10 @@ */ #include +#include #include #include + #include #include #include @@ -115,6 +117,48 @@ namespace AzToolsFramework return true; } + bool LoadInstanceFromPrefabDom( + Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& 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(&entityIdMapper)); + settings.m_metadata.Add(&entityIdMapper); + settings.m_metadata.Create(); + + 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(); + + referencedAssets = AZStd::move(assetTracker->GetTrackedAssets()); + return true; + } + bool LoadInstanceFromPrefabDom( Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadInstanceFlags flags) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index c4b988e36f..c7c2827770 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -13,6 +13,7 @@ #pragma once #include +#include #include #include @@ -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>& 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( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp index 5d8f1f35e3..a89b364471 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp @@ -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(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.cpp index ee45c258ff..78d1332a71 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.cpp @@ -56,6 +56,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return *m_asset; } + AZStd::vector>& ProcessedObjectStore::GetReferencedAssets() + { + return m_referencedAssets; + } + + const AZStd::vector>& ProcessedObjectStore::GetReferencedAssets() const + { + return m_referencedAssets; + } + AZStd::unique_ptr ProcessedObjectStore::ReleaseAsset() { return AZStd::move(m_asset); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h index a24d1f24c5..48e0007516 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h @@ -48,6 +48,10 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils AZ::Data::AssetData& GetAsset(); AZStd::unique_ptr ReleaseAsset(); + AZStd::vector>& GetReferencedAssets(); + const AZStd::vector>& GetReferencedAssets() const; + + const AZStd::string& GetId() const; private: @@ -55,6 +59,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils SerializerFunction m_assetSerializer; AZStd::unique_ptr m_asset; + AZStd::vector> m_referencedAssets; AZStd::string m_uniqueId; }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp index 713a5d8205..716c3098d9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp @@ -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> 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> referencedAssets; + return CreateSpawnable(spawnable, prefabDom, referencedAssets); + } + + bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector>& 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. { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h index 74cbbcb1e4..3b5ea488cb 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h @@ -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>& referencedAssets); void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable); } // namespace AzToolsFramework::Prefab::SpawnableUtils