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 <jillich@amazon.com>
This commit is contained in:
Benjamin Jillich
2021-10-19 18:28:24 +02:00
committed by GitHub
parent 005702b4bd
commit 08ff38a7f1
3 changed files with 25 additions and 1 deletions
@@ -6,7 +6,6 @@
*
*/
// include the required headers
#include "MorphTargetCommands.h"
#include "CommandManager.h"
#include <EMotionFX/Source/ActorManager.h>
@@ -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);
@@ -9,6 +9,8 @@
#include <EMotionFX/Pipeline/EMotionFXBuilder/EMotionFXBuilderComponent.h>
#include <EMotionFX/Source/Allocators.h>
#include <Integration/Assets/ActorAsset.h>
#include <Integration/Assets/MotionAsset.h>
#include <Integration/Assets/MotionSetAsset.h>
#include <Integration/Assets/AnimGraphAsset.h>
@@ -38,6 +40,8 @@ namespace EMotionFX
s_EMotionFXAllocator = AZ::Environment::CreateVariable<EMotionFXAllocatorInitializer>(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<EMotionFX::Integration::ActorAsset>());
assetCatalog->EnableCatalogForAsset(azrtti_typeid<EMotionFX::Integration::MotionAsset>());
assetCatalog->EnableCatalogForAsset(azrtti_typeid<EMotionFX::Integration::MotionSetAsset>());
assetCatalog->EnableCatalogForAsset(azrtti_typeid<EMotionFX::Integration::AnimGraphAsset>());
assetCatalog->AddExtension("actor"); // Actor
assetCatalog->AddExtension("motion"); // Motion
assetCatalog->AddExtension("motionset"); // Motion set
assetCatalog->AddExtension("animgraph"); // Anim graph
}
@@ -8,9 +8,11 @@
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <EMotionFX/Source/Actor.h>
#include <EMotionFX/Source/ActorManager.h>
#include <EMotionFX/Source/Importer/Importer.h>
#include <EMotionFX/CommandSystem/Source/MetaData.h>
#include <EMotionFX/Exporters/ExporterLib/Exporter/Exporter.h>
#include <Source/Integration/Assets/ActorAsset.h>
#include <SceneAPIExt/Rules/ActorPhysicsSetupRule.h>
#include <SceneAPIExt/Rules/SimulatedObjectSetupRule.h>
@@ -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<Integration::ActorAsset> actorAsset = AZ::Data::AssetManager::Instance().CreateAsset<Integration::ActorAsset>(actorAssetId);
actorAsset.GetAs<Integration::ActorAsset>()->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<EMotionFX::PhysicsSetup> physicsSetup;