Fix loaded procprefabs not going through the asset hint fixup process… (#6077)

* Fix loaded procprefabs not going through the asset hint fixup process for all versions of LoadInstanceFromPrefabDom.

Fixes procprefab asset references not working when pressing Ctrl+G in the editor

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Add unit test

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Add missing include

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
This commit is contained in:
amzn-mike
2021-12-07 13:00:47 -06:00
committed by GitHub
parent 1be7845cd2
commit 7c96bc4f1f
3 changed files with 214 additions and 25 deletions
@@ -150,6 +150,24 @@ namespace AzToolsFramework
return result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success;
}
// some assets may come in from the JSON serialzier with no AssetID, but have an asset hint
// this attempts to fix up the assets using the assetHint field
void FixUpInvalidAssets(AZ::Data::Asset<AZ::Data::AssetData>& asset)
{
if (!asset.GetId().IsValid() && !asset.GetHint().empty())
{
AZ::Data::AssetId assetId;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
assetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, asset.GetHint().c_str(),
AZ::Data::s_invalidAssetType, false);
if (assetId.IsValid())
{
asset.Create(assetId, false);
}
}
}
bool LoadInstanceFromPrefabDom(Instance& instance, const PrefabDom& prefabDom, LoadFlags flags)
{
// When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will
@@ -164,13 +182,17 @@ namespace AzToolsFramework
entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random);
}
auto tracker = AZ::Data::SerializedAssetTracker{};
tracker.SetAssetFixUp(&FixUpInvalidAssets);
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.Add(tracker);
AZ::JsonSerializationResult::ResultCode result =
AZ::JsonSerialization::Load(instance, prefabDom, settings);
@@ -203,13 +225,16 @@ namespace AzToolsFramework
entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random);
}
auto tracker = AZ::Data::SerializedAssetTracker{};
tracker.SetAssetFixUp(&FixUpInvalidAssets);
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>();
settings.m_metadata.Add(tracker);
AZ::JsonSerializationResult::ResultCode result =
AZ::JsonSerialization::Load(instance, prefabDom, settings);
@@ -246,29 +271,8 @@ namespace AzToolsFramework
entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random);
}
// some assets may come in from the JSON serialzier with no AssetID, but have an asset hint
// this attempts to fix up the assets using the assetHint field
auto fixUpInvalidAssets = [](AZ::Data::Asset<AZ::Data::AssetData>& asset)
{
if (!asset.GetId().IsValid() && !asset.GetHint().empty())
{
AZ::Data::AssetId assetId;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
assetId,
&AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath,
asset.GetHint().c_str(),
AZ::Data::s_invalidAssetType,
false);
if (assetId.IsValid())
{
asset.Create(assetId, false);
}
}
};
auto tracker = AZ::Data::SerializedAssetTracker{};
tracker.SetAssetFixUp(fixUpInvalidAssets);
tracker.SetAssetFixUp(&FixUpInvalidAssets);
AZ::JsonDeserializerSettings settings;
// The InstanceEntityIdMapper is registered twice because it's used in several places during deserialization where one is