
I am trying to trigger bullet casing sounds within the Niagara system for bullet shells ejected. I currently feed the static mesh information from the weapon data via “SetNiagaraVariable(StaticMesh).” I want to do the same for the sound to play, which has the type AudioPlayer. How do I make it and what node do I use to set it?
Bump…
Is this just not a thing in BP? Can it even be done with C++. Seems odd to have a one-shot audio playing capability and not be able to set it programmatically at runtime.
Hi, it is possible to set this at runtime, however this functionality isn’t exposed out of the box to Blueprints. You can however create a simple C++ function in a Blueprint library. A quick example inspired by functions in NiagaraFunctionLibrary would look like this:
Create a UNiagaraExtendedFunctionLibrary class derived from UBlueprintFunctionLibrary
In UNiagaraExtendedFunctionLibrary.h:
/** Sets the sound to play properties on an audio player data interface, this is destructive as it modifies the data interface. */
UFUNCTION(BlueprintCallable, Category = "Niagara", meta = (DisplayName = "Set Niagara Audio Player Properties"))
static void OverrideSystemUserVariableAudioPlayer(UNiagaraComponent* NiagaraSystem, const FString& OverrideName, USoundBase* SoundToPlay, USoundAttenuation* SoundAttenuation, USoundConcurrency* SoundConcurrency);
In UNiagaraExtendedFunctionLibrary.cpp:
#include "NiagaraComponent.h"
#include "NiagaraDataInterfaceAudioPlayer.h"
void UNiagaraExtendedFunctionLibrary::OverrideSystemUserVariableAudioPlayer(UNiagaraComponent* NiagaraSystem, const FString& OverrideName, USoundBase* SoundToPlay, USoundAttenuation* SoundAttenuation, USoundConcurrency* SoundConcurrency)
{
if (!NiagaraSystem)
{
UE_LOG(LogTemp, Warning, TEXT("NiagaraSystem in \"Override System User Variable Audio Player\" is NULL, OverrideName \"%s\", skipping."), *OverrideName);
return;
}
const FNiagaraParameterStore& OverrideParameters = NiagaraSystem->GetOverrideParameters();
FNiagaraVariable Variable(FNiagaraTypeDefinition(UNiagaraDataInterfaceAudioPlayer::StaticClass()), *OverrideName);
const int32 Index = OverrideParameters.IndexOf(Variable);
if (Index == INDEX_NONE)
{
UE_LOG(LogTemp, Warning, TEXT("UNiagaraExtendedFunctionLibrary::OverrideSystemUserVariableAudioPlayer: Did not find a matching Audio Player Data Interface variable named \"%s\" in the User variables of NiagaraSystem \"%s\"."), *OverrideName, *GetFullNameSafe(NiagaraSystem));
return;
}
UNiagaraDataInterfaceAudioPlayer* AudioPlayerInterface = Cast<UNiagaraDataInterfaceAudioPlayer>(OverrideParameters.GetDataInterface(Index));
AudioPlayerInterface->SoundToPlay = SoundToPlay;
AudioPlayerInterface->Attenuation = SoundAttenuation;
AudioPlayerInterface->Concurrency = SoundConcurrency;
}
And don’t forget to add “Niagara” into the PrivateDependencyModuleNames in your .Build.cs file.
After that you can call the node in Blueprint with your variable name:
you are right that there is no stock node for it. the set variable nodes only cover a small set of value types, and a data interface like the audio player param isnt one of them, so it never appears in the dropdown.
from c++ you can still do it. grab the interface off the component with UNiagaraFunctionLibrary::GetDataInterface(Comp, “YourParamName”), then set SoundToPlay, Attenuation and Concurrency on it and mark the render data dirty. that gives you per shot sounds without baking them into the system.
if you want it callable from blueprint, wrap that in a small blueprint function library, same pattern as the engine’s niagara function library.
you can also try Expose Niagara Variables C++ & Blueprints, a plugin for Unreal Engine that exposes Niagara variables to Blueprint and C++: Expose Niagara Variables to Blueprint & C++ — Set Niagara Parameters at Runtime | Fab
