Unreal 4 script which handles music playback by adding functionality to UAudioComponent as a child class
#include "Tacopocalypse.h" | |
#include "MusicTrackData.h" | |
#include "TacoSingleton.h" | |
#include "Engine.h" | |
#include "SoundDefinitions.h" | |
#include "MusicPlayerComponent.h" | |
// Sets default values for this component's properties | |
UMusicPlayerComponent::UMusicPlayerComponent() | |
{ | |
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features | |
// off to improve performance if you don't need them. | |
bWantsBeginPlay = true; | |
PrimaryComponentTick.bCanEverTick = true; | |
//bIsMusic = true; | |
//Load the music database which stores the locations of all of the music tracks | |
UMusicTrackData* LoadedMusicDatabase; | |
FString MusicDatabasePath = "/Game/TacoContent/Sound/Music/MusicTracksData.MusicTracksData"; | |
LoadedMusicDatabase = Cast<UMusicTrackData>(StaticLoadObject(UMusicTrackData::StaticClass(), NULL, *MusicDatabasePath, NULL, LOAD_None, NULL)); | |
NumSongs = LoadedMusicDatabase->SongList.Num(); | |
} | |
// Called when the game starts | |
void UMusicPlayerComponent::BeginPlay() | |
{ | |
Super::BeginPlay(); | |
} | |
// Called every frame | |
void UMusicPlayerComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) | |
{ | |
Super::TickComponent( DeltaTime, TickType, ThisTickFunction ); | |
//Checking to see if no music is playing, but music is available to play | |
//Sometimes music will refuse to play if not loaded asyncronously fast enough, this is a failsafe | |
if (IsLoadingMusic && LoadedSong != nullptr && IsPlaying() == false && this->Sound != nullptr) | |
{ | |
GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, TEXT("Trying to play because currently no song is playing -- may not have loaded in time")); | |
UE_LOG(LogTemp, Log, TEXT("Trying to play because currently no song is playing -- may not have loaded in time")); | |
Play(); | |
OnMusicLoadedDelegate.Broadcast(LoadedSong); | |
IsLoadingMusic = false; | |
} | |
else if (!IsLoadingMusic && LoadedSong != nullptr && IsPlaying() == false && this->Sound != nullptr) | |
{ | |
OnMusicFinishedPlaybackDelegate.Broadcast(); | |
GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, TEXT("Music finished playing")); | |
UE_LOG(LogTemp, Log, TEXT("Music finished playing")); | |
} | |
else if (IsLoadingMusic && IsPlaying() == true) | |
{ | |
IsLoadingMusic = false; | |
} | |
} | |
//Load the music Asyncronously, and then call BroadcastMusicLoaded() once loading has completed | |
void UMusicPlayerComponent::LoadMusic(int32 Index) | |
{ | |
TArray<FStringAssetReference> ObjToLoad; | |
UMusicTrackData* LoadedMusicDatabase; | |
FStreamableManager& BaseLoader = UTacoSingleton::GetSingleton().AssetLoader; | |
FString MusicDatabasePath = "/Game/TacoContent/Sound/Music/MusicTracksData.MusicTracksData"; | |
LoadedMusicDatabase = Cast<UMusicTrackData>(StaticLoadObject(UMusicTrackData::StaticClass(), NULL, *MusicDatabasePath, NULL, LOAD_None, NULL)); | |
//If our music database is valid, and the index requested falls within the song list array, load the given song | |
if (LoadedMusicDatabase != NULL && LoadedMusicDatabase->SongList.Num() > Index) | |
{ | |
MusicAssetToLoad = LoadedMusicDatabase->SongList[Index].MusicResource.ToStringReference(); | |
LoadedSongName = LoadedMusicDatabase->SongList[Index].ReturnFullName(); | |
ObjToLoad.AddUnique(MusicAssetToLoad); | |
} | |
IsLoadingMusic = true; | |
//NOTE -- Asyncronous loading currently not working, temporarily using syncronous load to ensure music is loading in time for playback (as of 5/19/16) | |
//Assign the event to be called once loading has finished | |
//BaseLoader.RequestAsyncLoad(ObjToLoad, FStreamableDelegate::CreateUObject(this, &UMusicPlayerComponent::BroadcastMusicLoaded)); | |
BaseLoader.SynchronousLoad(ObjToLoad[0]); | |
BroadcastMusicLoaded(); | |
} | |
//Broadcast the music finished loading event to the player blueprint and therefore it's HUD | |
void UMusicPlayerComponent::BroadcastMusicLoaded() | |
{ | |
//Ensure that the music has in fact been loaded | |
if (MusicAssetToLoad.ResolveObject() != nullptr) | |
{ | |
UObject* NewMusic = MusicAssetToLoad.ResolveObject(); | |
LoadedSong = Cast<USoundCue>(NewMusic); | |
//Assign the sound to the audio component | |
//SetSound() will automatically play the new song if another song is currently playing | |
SetSound(LoadedSong); | |
//Play if not playing | |
if (!IsPlaying()) | |
{ | |
Play(); | |
} | |
//Finally broadcast the blueprint event | |
OnMusicLoadedDelegate.Broadcast(LoadedSong); | |
//IsLoadingMusic = false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment