x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

UActorComponent::Rename() on a SkeletalMesh leads to a engine crash on unregistering the components!

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:

  1. The TargetActor gets the class of the actor to place and hands it to the GameplayAbilityWorldReticle_ActorVisualization (very nice name).

  2. The Reticle spawns an instance of the actor to place. Here, for the skeletal mesh component, a FAnimUpdateRateParameters struct is saved in the FAnimUpdateRateManager in a map during OnRegister(), using the owner actor as a key.. Then, detaches all mesh components from it and attaches it to itself.

  3. It calls UActorComponent::Rename() on all those mesh components and makes itself the outer of them.

  4. The actor to place, now without the mesh components, gets destroyed.

  5. Targeting can happen.

  6. When Targeting is finished, the Reticle gets destroyed, and with it all the mesh components. This is where the crash happens: During OnUnregister(), the FAnimUpdateRateParameters 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:

  1. Create a project with the Gameplay Abilities stuff enabled.

  2. Use The GameplayAbilityTargetActor_ActorPlacement class, e.g. with an AbilityTask_WaitTargetData, to place any actor that contains a SkeletalMeshComponent.

Steps to Reproduce the error more easily:

  1. 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]

Product Version: UE 4.21
Tags:
more ▼

asked Mar 06 '19 at 01:10 PM in C++ Programming

avatar image

minecrafter338
26 1 3

avatar image minecrafter338 Mar 08 '19 at 12:16 AM

Okay, since I don't know any better solution yet, I ended up copying two classes. My fix for this problem is to call UnregisterComponent() before Rename() and RegisterComponent() after it again, to have the right owner as key in the map in FAnimUpdateRateManager. To do this, I had to change and therefore copy the GameplayAbilityWorldReticle_ActorVisualization class, and to use my own class, the GameplayAbilityTargetActor_ActorPlacement class, too.

This is not too bad since these classes are really just examples on how to use the system, but well, copying code is never good. Also, there might be quite a bit of performance impact due to the reregistering of the component.

I am definitely open to better solutions! That is why I don't mark this question as answered. I hope that that is okay.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

0 answers: sort voted first
Be the first one to answer this question
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question