Random sound not actually random

For anyone else that reaches this page wondering about the random node not working. As Detach789 mentioned you can achieve the same results with the switch node. It just requires a little more setup. It works in both blueprint and C++.

First create your sound cue with the switch.

Then in either blueprint or c++ execute some logic on the audio player such as an AudioComponent.

Blueprint:

C++

Include module “AudioExtensions” in your project.build.cs file inside the PublicDependencyModuleNames.AddRange sub section.

Include this header in your .cpp file:
#include "AudioParameterControllerInterface.h"

Then in your code get a reference to the interface from the audio component to reference SetIntParameter().

It will look like this:

if (!MenuMusic)
{		
	return;
}	
	
AudioComponent->SetSound(MenuMusic);
	
if (IAudioParameterControllerInterface* Interface = Cast<IAudioParameterControllerInterface>(AudioComponent))
{
     Interface->SetIntParameter("MenuMusic", FMath::RandRange(0, 18));
}

AudioComponent->Play(0.0f);

Just be very careful with the RandRange function. Be sure not to put values that are outside the range of the switch in your cue.

** Note **

After testing this, I found that if you are using a looper node in the sound cue it will simply loop the same index in the switch over and over. So, in this case you want to remove the looper and bind an event from the audio component called OnAudioFinished()

This can be done in both blueprint and c++. The blueprint way is the normal way you bind regular delegates.

In c++ it looks like this:

In your class header file, create a UFUNCTION() function that will bind to the audio component delegate:

.h

UFUNCTION()
void OnAudioFinished()

In your cpp file add the below logic to begin play and the logic for changing the switch parameter and playing the audio component again inside your new bound function:

.cpp

void AYourActor::BeginPlay()
{
     AudioComponent->OnAudioFinished.AddDynamic(this, &AYourActor::OnAudioFinished();
}

void AYourActor::OnAudioFinished()
{
     if (IAudioParameterControllerInterface* Interface = Cast<IAudioParameterControllerInterface>(AudioComponent))
	{
		if (bIsMainMenuActive)
		{			
			Interface->SetIntParameter("MenuMusic", FMath::RandRange(MenuAudioIndexMin, MenuAudioIndexMax));
			AudioComponent->Play(0.0f);
		}
		else
		{
			Interface->SetIntParameter("GameplayMusic", FMath::RandRange(GameplayAudioIndexMin, GameplayAudioIndexMax));
			AudioComponent->Play(0.0f);
		}
	}
}

In my code I even made a few UPROPERTY variables in my player controller that I use to define the min and max values of sound cue waves.

1 Like