From 0f5964be0885d6135f29835a45185ab7593d01b5 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Mon, 8 Mar 2021 02:22:10 -0500 Subject: [PATCH] Sound actor destroys itself after play --- .../Private/SoundSpawnActor.cpp | 50 ++++++++++++++++--- .../Private/SpawningActor.cpp | 11 +--- .../Public/SoundSpawnActor.h | 26 +++++++++- .../Public/SpawningActor.h | 6 +-- 4 files changed, 69 insertions(+), 24 deletions(-) diff --git a/Source/ActorSpawningPlugin/Private/SoundSpawnActor.cpp b/Source/ActorSpawningPlugin/Private/SoundSpawnActor.cpp index b5a43e7..34f0aef 100644 --- a/Source/ActorSpawningPlugin/Private/SoundSpawnActor.cpp +++ b/Source/ActorSpawningPlugin/Private/SoundSpawnActor.cpp @@ -1,19 +1,28 @@ #include "SoundSpawnActor.h" -#include "UObject/Object.h" -#include "Kismet/GameplayStatics.h" +#include "Components/AudioComponent.h" #include "Components/BillboardComponent.h" +#include "Kismet/GameplayStatics.h" +#include "UObject/Object.h" DEFINE_LOG_CATEGORY(SoundSpawnActorLog); ASoundSpawnActor::ASoundSpawnActor(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer), - BillboardComponent(nullptr) + BillboardComponent(nullptr), + HasSoundStarted(false), + DoDestroyAfterSoundPlays(false) { UE_LOG(SoundSpawnActorLog, Log, TEXT("CTOR()")); BillboardComponent = CreateDefaultSubobject(TEXT("Billboard")); BillboardComponent->SetupAttachment(RootComponent); + + AudioComponent = CreateDefaultSubobject(TEXT("Audio")); + AudioComponent->SetupAttachment(BillboardComponent); + + // We use tick to kill the actor when the sound is done playing + PrimaryActorTick.bCanEverTick = true; } ASoundSpawnActor::~ASoundSpawnActor() @@ -31,6 +40,29 @@ void ASoundSpawnActor::BeginDestroy() } void ASoundSpawnActor::SetSound(USoundBase* sound) +{ + AudioComponent->SetSound(sound); +} + +void ASoundSpawnActor::SetSprite(UTexture2D* sprite) +{ + BillboardComponent->SetSprite(sprite); + BillboardComponent->RegisterComponent(); + BillboardComponent->bHiddenInGame = false; // NB: This defaults to true! :( +} + +void ASoundSpawnActor::PlaySoundWithSprite(USoundBase* sound, UTexture2D* sprite, bool DestroyAfterPlay) +{ + SetSprite(sprite); + SetSound(sound); + + AudioComponent->Play(0.0); + + HasSoundStarted = true; + DoDestroyAfterSoundPlays = DestroyAfterPlay; +} + +void ASoundSpawnActor::PlaySoundImmediate(USoundBase* sound) { UE_LOG(SoundSpawnActorLog, Log, TEXT("playing sound...")); @@ -43,10 +75,14 @@ void ASoundSpawnActor::SetSound(USoundBase* sound) ); } -void ASoundSpawnActor::SetSprite(UTexture2D* sprite) +void ASoundSpawnActor::Tick(float DeltaTime) { - BillboardComponent->SetSprite(sprite); - BillboardComponent->RegisterComponent(); - BillboardComponent->bHiddenInGame = false; // NB: This defaults to true! :( + Super::Tick(DeltaTime); + + if (HasSoundStarted + && DoDestroyAfterSoundPlays + && !AudioComponent->IsPlaying()) { + Destroy(); + } } diff --git a/Source/ActorSpawningPlugin/Private/SpawningActor.cpp b/Source/ActorSpawningPlugin/Private/SpawningActor.cpp index 9ea2778..ba24634 100644 --- a/Source/ActorSpawningPlugin/Private/SpawningActor.cpp +++ b/Source/ActorSpawningPlugin/Private/SpawningActor.cpp @@ -100,7 +100,7 @@ ASpawnableSkeletalMeshActor* ASpawningActor::SpawnSkeletalMeshActor() return spawnedActor; } -ASoundSpawnActor* ASpawningActor::SpawnSoundActor(USoundBase* sound) +ASoundSpawnActor* ASpawningActor::SpawnSoundActor() { FVector playerLocation = LookupPlayerLocation(); @@ -127,15 +127,6 @@ ASoundSpawnActor* ASpawningActor::SpawnSoundActor(USoundBase* sound) actorSpawnParams ); - actor->SetSound(sound); - - return actor; -} - -ASoundSpawnActor* ASpawningActor::SpawnSoundActorWithText(USoundBase* sound, const FString& text) -{ - ASoundSpawnActor* actor = SpawnSoundActor(sound); - return actor; } diff --git a/Source/ActorSpawningPlugin/Public/SoundSpawnActor.h b/Source/ActorSpawningPlugin/Public/SoundSpawnActor.h index 6073257..3d03803 100644 --- a/Source/ActorSpawningPlugin/Public/SoundSpawnActor.h +++ b/Source/ActorSpawningPlugin/Public/SoundSpawnActor.h @@ -20,11 +20,15 @@ public: ASoundSpawnActor(const FObjectInitializer& ObjectInitializer); ~ASoundSpawnActor(); - /** Access to the optional billboard component */ + /** Access to the audio component */ + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SoundSpawnActor") + class UAudioComponent* AudioComponent; + + /** Access to the billboard component */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SoundSpawnActor") class UBillboardComponent* BillboardComponent; - /** Set the sound. */ + /** Set sound to the audio component. */ UFUNCTION(BlueprintCallable, Category = "SoundSpawnActor") void SetSound(USoundBase* sound); @@ -32,7 +36,25 @@ public: UFUNCTION(BlueprintCallable, Category = "SoundSpawnActor") void SetSprite(UTexture2D* sprite); + /** Play sound with the sprite, then destroy. */ + UFUNCTION(BlueprintCallable, Category = "SoundSpawnActor") + void PlaySoundWithSprite(USoundBase* sound, UTexture2D* sprite, bool DestroyAfterPlay); + + /** Play a sound. Does not set to the component. */ + UFUNCTION(BlueprintCallable, Category = "SoundSpawnActor") + void PlaySoundImmediate(USoundBase* sound); + + // Called every frame + // Used to invoke destroy. + virtual void Tick(float DeltaTime) override; + protected: + // Whether sound has started playing at any point. + bool HasSoundStarted; + + // Whether to destroy after sound finishes playing the first time. + bool DoDestroyAfterSoundPlays; + // Called when the game starts or when spawned virtual void BeginPlay() override; diff --git a/Source/ActorSpawningPlugin/Public/SpawningActor.h b/Source/ActorSpawningPlugin/Public/SpawningActor.h index 919b277..4f2f603 100644 --- a/Source/ActorSpawningPlugin/Public/SpawningActor.h +++ b/Source/ActorSpawningPlugin/Public/SpawningActor.h @@ -34,11 +34,7 @@ public: /** Create sound actor. */ UFUNCTION(BlueprintCallable, Category = "SpawningActor") - ASoundSpawnActor* SpawnSoundActor(USoundBase* sound); - - /** Create sound actor with text. */ - UFUNCTION(BlueprintCallable, Category = "SpawningActor") - ASoundSpawnActor* SpawnSoundActorWithText(USoundBase* sound, const FString& text); + ASoundSpawnActor* SpawnSoundActor(); /** Mesh to use */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpawningActor", meta = (AllowPrivateAccess = "true"))