Download

How to prevent UAudioComponent from being "nulled"

Hello there!

Let’s go to the point.

This is how I’m creating my component:
.h


UPROPERTY()
        UAudioComponent* AudioComponent;

.cpp


UAudioComponent* UAudioController::Sound2D(UObject* WorldContextObject, class USoundBase* Sound, float VolumeMultiplier, float PitchMultiplier, float StartTime)
{
    if (!Sound)
    {
        return nullptr;
    }

    AudioComponent = UGameplayStatics::CreateSound2D(WorldContextObject, Sound, VolumeMultiplier, PitchMultiplier, StartTime);
    PlaybackPositionMap.Add(AudioComponent, 0.f);
    BindDelegates(AudioComponent);
    AudioComponent->Play(StartTime);
    return AudioComponent;
}

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 :slight_smile:

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.

Ensure it also has bAutoDestroy set to false.

So my pointer is stored in this class


 

  1. #pragma once
  1. #include "CoreMinimal.h"
  1. #include "Components/ActorComponent.h"
  1. #include "AudioController.generated.h"
  1. USTRUCT(BlueprintType)
  1. struct FAudioComponentPlaybackPosition
  1. {
  1. GENERATED_BODY()
  1. UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "AudioController")
  1. UAudioComponent* AudioComponent;
  1. UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "AudioController")
  1. float PlaybackPosition;
  1. FAudioComponentPlaybackPosition()
  1. {
  1. AudioComponent = nullptr;
  1. PlaybackPosition = 0.f;
  1. }
  1. FAudioComponentPlaybackPosition(UAudioComponent* AComponent, float NewPlaybackPosition)
  1. {
  1. AudioComponent = AComponent;
  1. PlaybackPosition = NewPlaybackPosition;
  1. }
  1. };
  1. UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
  1. class MYGAME_API UAudioController : public UActorComponent
  1. {
  1. GENERATED_BODY()
  1. public:
  1. // Sets default values for this component's properties
  1. UAudioController();
  1. protected:
  1. // Called when the game starts
  1. virtual void BeginPlay() override;
  1. public:
  1. // Called every frame
  1. virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
  1. //UFUNCTION(BlueprintCallable, Category = "Test")
  1. // void LambdaTesting();
  1. UFUNCTION(BlueprintCallable, Category = "AudioController", meta=(HidePin="WorldContextObject", WorldContext="WorldContextObject"))
  1. UAudioComponent* Sound2D(UObject* WorldContextObject,class USoundBase* Sound, float VolumeMultiplier = 1.f, float PitchMultiplier = 1.f, float StartTime = 0.f);
  1. UFUNCTION(Category = "AudioController")
  1. void SavePlaybackPosition(const USoundWave* SoundWave, const float PlaybackPercent);
  1. UFUNCTION(Category="AudioController")
  1. void SoundFinished();
  1. UFUNCTION(Category = "AudioController")
  1. void BindDelegates(UAudioComponent* AudioComponent);
  1. UFUNCTION(Category = "AudioController")
  1. void UnbindDelegates(UAudioComponent* AudioComponent);
  1. //UFUNCTION(BlueprintCallable, Category = "AudioController", meta = (HidePin = "WorldContextObject", WorldContext = "WorldContextObject"))
  1. //UAudioComponent* LambdaSound2D(UObject* WorldContextObject, class USoundBase* Sound, FTimerHandle &TimerHandle, float VolumeMultiplier = 1.f, float PitchMultiplier = 1.f, float StartTime = 0.f);
  1. UFUNCTION(BlueprintImplementableEvent, Category = "AudioController")
  1. void OnAudioFinishedPlaying(UAudioComponent* AudioComponent);
  1. UFUNCTION(BlueprintCallable, Category = "AudioController")
  1. void PauseDialogue(bool SetPaused, FTimerHandle TimerHandle);
  1. UPROPERTY()
  1. TMap<UAudioComponent*, float> PlaybackPositionMap;
  1. UPROPERTY()
  1. UAudioComponent* AudioComponent;
  1. };

 

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?