Created
May 26, 2017 23:20
-
-
Save braustin20/410c897264e5f5d6b5c7f1cf44f92df5 to your computer and use it in GitHub Desktop.
Unreal 4 script which handles music playback by adding functionality to UAudioComponent as a child class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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