Hello guys,
I stumbled across this when using the GameplayAbilityTargetActor_ActorPlacement
with an actor that contains a SkeletalMeshComponent
. I need a way to be able to use SkeletalMeshComponents on these actors!
What happens is the following:
- The TargetActor gets the class of the actor to place and hands it to the
GameplayAbilityWorldReticle_ActorVisualization
(very nice name). - The Reticle spawns an instance of the actor to place. Here, for the skeletal mesh component, a
FAnimUpdateRateParameters
struct is saved in theFAnimUpdateRateManager
in a map duringOnRegister()
, using the owner actor as a key.. Then, detaches all mesh components from it and attaches it to itself. - It calls UActorComponent::Rename() on all those mesh components and makes itself the outer of them.
- The actor to place, now without the mesh components, gets destroyed.
- Targeting can happen.
- When Targeting is finished, the Reticle gets destroyed, and with it all the mesh components. This is where the crash happens: During
OnUnregister()
, theFAnimUpdateRateParameters
should get deleted, but the owner that is used as a key to find them has changed! This results in a failed assert!
The UActorComponent::Rename()
method is called in AGameplayAbilityWorldReticle_ActorVisualization::InitializeReticleVisualizationInformation()
, if that helps someone.
Steps to Reproduce the error like I got it:
- Create a project with the Gameplay Abilities stuff enabled.
- Use The
GameplayAbilityTargetActor_ActorPlacement
class, e.g. with anAbilityTask_WaitTargetData
, to place any actor that contains aSkeletalMeshComponent
.
Steps to Reproduce the error more easily:
-
UActorComponent::Rename()
a skeletal mesh component to have another actor as outer and the other actor.
It would be very very nice if someone could help me in finding a workaround for this problem! Is this a bug and the programmers have not thought about it or am I doing something wrong?
Thanks in advance!
Relevant part of the crash report:
Assertion failed: Pair != nullptr [File:D:\Build\++UE4\Sync\Engine\Source\Runtime\Core\Public\Containers/Map.h] [Line: 476]
UE4Editor_Core!FDebug::AssertFailed() [d:\build\++ue4\sync\engine\source\runtime\core\private\misc\assertionmacros.cpp:417]
UE4Editor_Engine!FAnimUpdateRateManager::CleanupUpdateRateParametersRef() [d:\build\++ue4\sync\engine\source\runtime\engine\private\components\skinnedmeshcomponent.cpp:159]
UE4Editor_Engine!USkeletalMeshComponent::OnUnregister() [d:\build\++ue4\sync\engine\source\runtime\engine\private\components\skeletalmeshcomponent.cpp:617]
UE4Editor_Engine!UActorComponent::ExecuteUnregisterEvents() [d:\build\++ue4\sync\engine\source\runtime\engine\private\components\actorcomponent.cpp:1280]
UE4Editor_Engine!UActorComponent::UnregisterComponent() [d:\build\++ue4\sync\engine\source\runtime\engine\private\components\actorcomponent.cpp:1066]
UE4Editor_Engine!AActor::UnregisterAllComponents() [d:\build\++ue4\sync\engine\source\runtime\engine\private\actor.cpp:4118]
UE4Editor_Engine!UWorld::DestroyActor() [d:\build\++ue4\sync\engine\source\runtime\engine\private\levelactor.cpp:694]
UE4Editor_Engine!AActor::Destroy() [d:\build\++ue4\sync\engine\source\runtime\engine\private\actor.cpp:3698]
UE4Editor_GameplayAbilities!AGameplayAbilityTargetActor_ActorPlacement::EndPlay() [d:\build\++ue4\sync\engine\plugins\runtime\gameplayabilities\source\gameplayabilities\private\abilities\gameplayabilitytargetactor_actorplacement.cpp:25]
UE4Editor_Engine!AActor::Destroyed() [d:\build\++ue4\sync\engine\source\runtime\engine\private\actor.cpp:2086]
UE4Editor_Engine!UWorld::DestroyActor() [d:\build\++ue4\sync\engine\source\runtime\engine\private\levelactor.cpp:592]
UE4Editor_Engine!AActor::Destroy() [d:\build\++ue4\sync\engine\source\runtime\engine\private\actor.cpp:3698]
UE4Editor_GameplayAbilities!UAbilityTask_WaitTargetData::OnDestroy() [d:\build\++ue4\sync\engine\plugins\runtime\gameplayabilities\source\gameplayabilities\private\abilities\tasks\abilitytask_waittargetdata.cpp:350]
UE4Editor_GameplayTasks!UGameplayTask::EndTask() [d:\build\++ue4\sync\engine\source\runtime\gameplaytasks\private\gameplaytask.cpp:173]
UE4Editor_GameplayAbilities!UAbilityTask_WaitTargetData::OnTargetDataReadyCallback() [d:\build\++ue4\sync\engine\plugins\runtime\gameplayabilities\source\gameplayabilities\private\abilities\tasks\abilitytask_waittargetdata.cpp:291]
UE4Editor_GameplayAbilities!TBaseUObjectMethodDelegateInstance<0,UAbilityTask_WaitTargetData const ,void __cdecl(FGameplayAbilityTargetDataHandle const & __ptr64)>::ExecuteIfSafe() [d:\build\++ue4\sync\engine\source\runtime\core\public\delegates\delegateinstancesimpl.h:679]
UE4Editor_GameplayAbilities!TBaseMulticastDelegate<void,FGameplayAbilityTargetDataHandle const & __ptr64>::Broadcast() [d:\build\++ue4\sync\engine\source\runtime\core\public\delegates\delegatesignatureimpl.inl:974]
UE4Editor_GameplayAbilities!AGameplayAbilityTargetActor_Trace::ConfirmTargetingAndContinue() [d:\build\++ue4\sync\engine\plugins\runtime\gameplayabilities\source\gameplayabilities\private\abilities\gameplayabilitytargetactor_trace.cpp:203]
UE4Editor_GameplayAbilities!AGameplayAbilityTargetActor::ConfirmTargeting() [d:\build\++ue4\sync\engine\plugins\runtime\gameplayabilities\source\gameplayabilities\private\abilities\gameplayabilitytargetactor.cpp:94]