From 08ff38a7f109a0b5a5e0071e02f48ee94b1118b0 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Tue, 19 Oct 2021 18:28:24 +0200 Subject: [PATCH] EMotion FX: Adding/Removing/Changing Components to an Entity with Actor Component erases the "Motion extraction joint" (#4780) Applying meta data onto actors failed as the commands use the actor manager to search them by ID but the actor manager now stores actor assets. The temporarily created actor in the actor exporter was not registered at the actor manager for that reason and the commands were failing to find the actor. This resulted in that all meta data for actors could not be applied on the actors. Signed-off-by: Benjamin Jillich --- .../CommandSystem/Source/MorphTargetCommands.cpp | 7 ++++++- .../EMotionFXBuilder/EMotionFXBuilderComponent.cpp | 8 ++++++++ .../Pipeline/RCExt/Actor/ActorGroupExporter.cpp | 11 +++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MorphTargetCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MorphTargetCommands.cpp index 0a48952bfc..3ec4b9b894 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MorphTargetCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MorphTargetCommands.cpp @@ -6,7 +6,6 @@ * */ -// include the required headers #include "MorphTargetCommands.h" #include "CommandManager.h" #include @@ -110,6 +109,12 @@ namespace CommandSystem actor = actorInstance->GetActor(); } + if (!actor) + { + AZ_Error("EMotionFX", false, "Cannot adjust morph target. Actor with ID %i cannot be found.", actorID); + return false; + } + // get the level of detail to work on const uint32 lodLevel = parameters.GetValueAsInt("lodLevel", this); diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/EMotionFXBuilderComponent.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/EMotionFXBuilderComponent.cpp index 85b2b0fe3d..43222f9538 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/EMotionFXBuilderComponent.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/EMotionFXBuilderComponent.cpp @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include @@ -38,6 +40,8 @@ namespace EMotionFX s_EMotionFXAllocator = AZ::Environment::CreateVariable(EMotionFXAllocatorInitializer::EMotionFXAllocatorInitializerTag); // Initialize asset handlers. + m_assetHandlers.emplace_back(aznew EMotionFX::Integration::ActorAssetHandler); + m_assetHandlers.emplace_back(aznew EMotionFX::Integration::MotionAssetHandler); m_assetHandlers.emplace_back(aznew EMotionFX::Integration::MotionSetAssetBuilderHandler); m_assetHandlers.emplace_back(aznew EMotionFX::Integration::AnimGraphAssetBuilderHandler); @@ -45,9 +49,13 @@ namespace EMotionFX auto assetCatalog = AZ::Data::AssetCatalogRequestBus::FindFirstHandler(); if (assetCatalog) { + assetCatalog->EnableCatalogForAsset(azrtti_typeid()); + assetCatalog->EnableCatalogForAsset(azrtti_typeid()); assetCatalog->EnableCatalogForAsset(azrtti_typeid()); assetCatalog->EnableCatalogForAsset(azrtti_typeid()); + assetCatalog->AddExtension("actor"); // Actor + assetCatalog->AddExtension("motion"); // Motion assetCatalog->AddExtension("motionset"); // Motion set assetCatalog->AddExtension("animgraph"); // Anim graph } diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp index 3d5e4fa413..baa2984d4f 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp @@ -8,9 +8,11 @@ #include #include +#include #include #include #include +#include #include #include @@ -82,10 +84,19 @@ namespace EMotionFX AZStd::string metaDataString; if (Rule::MetaDataRule::LoadMetaData(actorGroup, metaDataString)) { + // Create a temporary actor asset as the commands use the actor manager to find the corresponding actor object + // and our actor can only be found as part of a registered actor asset. + const AZ::Data::AssetId actorAssetId = AZ::Data::AssetId(AZ::Uuid::CreateRandom()); + AZ::Data::Asset actorAsset = AZ::Data::AssetManager::Instance().CreateAsset(actorAssetId); + actorAsset.GetAs()->SetData(m_actor); + GetEMotionFX().GetActorManager()->RegisterActor(actorAsset); + if (!CommandSystem::MetaData::ApplyMetaDataOnActor(m_actor.get(), metaDataString)) { AZ_Error("EMotionFX", false, "Applying meta data to actor '%s' failed.", m_actor->GetName()); } + + GetEMotionFX().GetActorManager()->UnregisterActor(actorAsset->GetId()); } AZStd::shared_ptr physicsSetup;