Quick explain about BindDelegates and PlaybackPositionMap:
BindDelegates contains OnAudioPlaybackPercent and OnAudioFinished binds.
PlaybackPositionMap holds AudioComponent with float value which is self explaining. Just need access to time played.
What is the problem?
When I’ll just play sound it’s all great and delegates works perfectly, but if I’ll pause game for let’s say 1 minute, then come back and unpause it, suddenly my AudioComponent is null. It cannot be unpaused and played at all.
So my question is why is that and how can I prevent it from happening? I was thinking that reason is AudioComponent not being UPROPERTY() before but that also failed.
If there is any further information needed, let me know
Where is the pointer to the Audio Component stored? If the pointer is not inside another reflected type then it will still be GC’d regardless of whether it’s a UPROPERTY or not.
I will try to set bAutoDestroy to false. Also i googled what exactly reflection is and found this link: Unreal Property System (Reflection) - Unreal Engine
Does this mean I need change my GENERATED_BODY() to GENERATED_UCLASS_BODY() to make it know that it’s reflected type or there is more to this?
I think I’m witnessing this too. I have a very basic call to UGameplayStatics::SpawnSound2D and I store the return of that. I later check it, and if its valid, I made a FadeOut call. But apparently, it nulls out between the check and the call anyway so it crashes. Its very rare, but I’ve observed it with a dump too. UE4.26.2
That’s a very strange code style for working in Unreal. You should use IsValid() to check the ptr, and you should m ake sure the pointer is held in a UPROPERTY … and that it’s not auto destroying itself.
IsValid() also does the same thing, the only difference is that it checks for pending kill flag. Even swapping out the nullptr check with IsValid, the crash still occurs (again, not 100% of the time)
But, you may be onto something with auto destroy.
UGameplayStatics::SpawnSound2D has a default parameter of true for auto destroy. So is it possible that Unreal is destroying it in a different thread? It’s the only explanation I can think of bypassing a nullptr check and IsValid() If it was destroying on the same thread, then it would be null already or after the call, not during it.
When I investigate the mini dump in the debugger, the other threads are not doing anything. Specifically the audio thread is waiting at the time of the call. But that also doesn’t mean it didn’t do it prior to handling the destroy or something. Or it could be one of the many other threads doing something Im unfamiliar with.
bAutoDestroy simply means that when the sound stops playing, the component destroys itself.
Disabling that, will not affect the rest of the component lifecycle.
For usual usecases this means you don’t need to manually call Destroy on it. However, if you have this component dynamically created by a parent component, then it might be useful to call Destroy on the DestroyComponent override of the parent component. (I say dynamically because statically created in a component constructor isn’t officially supported)
Thank you for mention that, it’s exactly my case. I create UAudioComponent on BeginPlay of UActorComponent with UGameplayStatics::CreateSound2D function and Play/Stop it during the session.
Thank you very much. I was struggling to find the cause. It was because of auto-destroy for my case as well. Was also using UGameplayStatics::SpawnSound2D() function.