Can I instantiate volumes through code?

Is there any way to create a volume (specifically a post-effects volume) through code, preferably Blueprints?

I have a class of moving actor that affects the player’s vision via post-effects the closer that they get to it. As such I need a post-effects volume to remain attached to these actors as they move. The problem is that I can see no way to add a volume as a component. I can parent a volume to an actor in the editor just fine, but I need to be able to do this at runtime. If I try to create a composited Blueprint out of the hand-created actor/volume hybrid, it just detaches the volume.

If there’s another way to achieve this, I’d also be interested in hearing. My current backup plan is to interpolate the effects directly onto the player’s camera based on distance to any of these actors every tick, but that sounds both painstaking and inefficient.

Hey SF,

There are certainly many ways to achieve the effect you’re looking for. An easy way would be to create a Post Process Volume and set it to Unbound so it affects the camera no matter where it is. Then in your Level Blueprint (or character blueprint, or moving object’s blueprint, etc), turn it on or off depending on whether the player is within a certain range of the moving objects.

But there’s more! I just checked our internal build, and the ability to add a Post Process Volume as a component inside a Blueprint is there. It’s on it’s way! I can’t give you a firm date for that, but you should be able to do that soon.

Ben Halliday

Hi Ben,

So in the future it will be possible to spawn a post process volume on a dynamic actor’s location via Blueprint? Am I correct in assuming that currently there is no solution for blending a post process volume relating to the distance a pawn is from a dynamic actor? Hopefully, that makes sense.

Thanks,

— Ben.

Thanks for the suggestion with the unbound effect! That should work in the meanwhile.

And that’s great news about the coming feature, thank you very much for checking! Firm date aside, I don’t suppose you have a guess as to whether it’d be coming more on the order of days, weeks, or months? Just so I know whether I should wait for it on my current project.

hi everyone!

i just discovered that this code works:

	UObject* PostProcessVolumeObj = FindObject<UObject>(nullptr, TEXT("/Script/Engine.PostProcessVolume"));
	UActorFactory* PostProcessVolumeFactory = GEditor->FindActorFactoryByClassForActorClass(UActorFactoryBoxVolume::StaticClass(), APostProcessVolume::StaticClass());
	APostProcessVolume* PostProcessVolume = Cast<APostProcessVolume>(PostProcessVolumeFactory->CreateActor(PostProcessVolumeObj, ComplementsWorld->PersistentLevel, FTransform()));

first you get the uobject that represent PP asset;
then you get the factory to construct it;
finally you use that factory to create your final actor!

you can use the same code to spawn all others volume related actors, for example:

	UObject* NavMeshBoundsVolumeObj = FindObject<UObject>(nullptr, TEXT("/Script/Engine.NavMeshBoundsVolume"));
	UActorFactory* NavMeshBoundsVolumeFactory = GEditor->FindActorFactoryByClassForActorClass(UActorFactoryBoxVolume::StaticClass(), ANavMeshBoundsVolume::StaticClass());
	ANavMeshBoundsVolume* NavMeshBoundsVolume = Cast<ANavMeshBoundsVolume>(NavMeshBoundsVolumeFactory->CreateActor(NavMeshBoundsVolumeObj, ComplementsWorld->PersistentLevel, FTransform()));

or

	UObject* LightmassImportanceVolumeObj = FindObject<UObject>(nullptr, TEXT("/Script/Engine.LightmassImportanceVolume"));
	UActorFactory* LightmassImportanceVolumeFactory = GEditor->FindActorFactoryByClassForActorClass(UActorFactoryBoxVolume::StaticClass(), ALightmassImportanceVolume::StaticClass());
	ALightmassImportanceVolume* LightmassImportanceVolume = Cast<ALightmassImportanceVolume>(LightmassImportanceVolumeFactory->CreateActor(LightmassImportanceVolumeObj, ComplementsWorld->PersistentLevel, FTransform()));

Bye :wink:

1 Like