Skip to content

Instantly share code, notes, and snippets.

@braustin20
Created May 26, 2017 23:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save braustin20/410c897264e5f5d6b5c7f1cf44f92df5 to your computer and use it in GitHub Desktop.
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
#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