Is it possible to render mesh passed to Niagara?

I would like to use a mesh passed to Niagara through a user parameter from a blueprint, as a particle. Is this possible?

I know there are Mesh Renderers and they can have a list of meshes and each particle can pick from that list with an index, but I could have as many as 2000 meshes, so this method is very impractical.

I also know I can reproduce the mesh with many particles through the mesh samplers, but this never produces 100% accurate representation of the mesh, and also does not seem like an efficient method considering a single particle with the correct mesh would work.

So the problem is I can’t seem to set the Mesh Renderer’s mesh with the User Parameter, is there a workaround for this?

Thanks for any help.

Hey there @Rjktlf1! Welcome to the community! So don’t worry, this is actually one of the fun quirks of the Niagara systems. So you can still use user parameters, but you can’t drag and drop bind them because you can have multiple meshes. However there is a setting to bind them directly.

So make a user param for your static mesh, the go to the mesh renderer, drop down the meshes area, then drop down the index of the mesh you’d like bound, then there’s little slot for binding to a user parameter. Don’t worry if you have a default bound mesh or not, it won’t show until that parameter is set. So in my case the default arrows remain the used mesh until the parameter is not null, then the parameter is what’s used.

Let me know if you have any questions!

Hi @SupportiveEntity, thank you for the reply.

It looks like you are using UE5, the slot for doing this does not appear to be in UE4.27. Do you know if there is a way to do this in 4.27? Unfortunately I am not able to upgrade to UE5 for this project.

Oh hey sorry about that @Rjktlf1! Was handpicking a bunch of UE5 questions while I had it open and guess I missed the tag this time around. So in UE4 it was a little more complicated to pull that off. There was no standard binding so you’d have to create your own module in scratchpad, or if you know exactly what meshes you wanted to possible change to, you can change the mesh index and just set them all as possible meshes. You can bind it to an int.
image

Thanks @SupportiveEntity, I did already know about filling in that Meshes array and picking an index, however I could potentially have hundreds of meshes, this way is not realistic imo.

Could you give me a few pointers, or nodes that will be needed for passing the mesh in to be rendered with my own scratchpad module?

Thanks

Hey there @Rjktlf1! Sorry for the late reply, I’ve been playing with scratch pad myself trying to find a good way to pull it off, but that module doesn’t expose any of it’s mesh-side logic (more so there’s no internal binding at all). I had made up a module that could take a list of meshes, and process them but outputting only goes to a bindable, which leads us back to the original problem. Sorry was hoping to make the module for you and post it here but it didn’t seem like that method is going to work either.

Ok @SupportiveEntity, Ill use another method for now. Thanks for trying it out, I can move on knowing I wasn’t missing something.
Cheers.

1 Like

I’m running into the same issue. What did you do for a work-around? Thanks

Hi @Kdupuy, in the end I used the Sample Static Mesh and Static Mesh Location modules to reproduce the mesh with around 250 particles. The effect is quick enough it does the job. I also ticked the box Support Uniformly Distributed Sampling in the Mesh Editor General Settings so my mesh poly density did not need to be uniform.
The backup option is to just do the single mesh animation in a blueprint and apply particle effects over the top.


image

1 Like

I’m currently trying to solve this as well, to set or change Niagara meshes at runtime. The only “real” solution I found for UE4.27 is a complete hack. Basically overwriting the actual static mesh data itself. For example say you have a static mesh Cube in your Niagara Mesh Renderer. You can overwrite the Cube mesh itself to become a Sphere. But all static meshes that use the Cube reference will also change into Spheres too! lmao.

Here’s the code snippet, which only works in the editor for now.

void URuntimeMeshLibrary::OverWriteMesh(UStaticMesh* Mesh, UStaticMesh* NewMesh)
{
	FMeshDescription& Okay = *NewMesh->GetMeshDescription(0);
	FStaticMeshLODResources& Lod = NewMesh->GetRenderData()->LODResources[0];

	TArray<const FMeshDescription*> MeshDescriptionPtrs;
	MeshDescriptionPtrs.Emplace(&Okay);
	Mesh->BuildFromMeshDescriptions(MeshDescriptionPtrs);
}

That specific code doesn’t work in a Packaged Build, because “GetMeshDescription” only compiles for use with the Editor. So a bit more code would be needed to copy the mesh data manually. In theory this idea should work, but you’ll also have to create dummy static meshes and my case, I’ll have hundreds/thousands of potential meshes. And will need to create hundreds of dummy niagara systems…

1 Like

Oh resourceful! That said, building from source you could technically splice in the UE5 Niagara changes that allow for user targeted, but it’d probably be even more hacky if you have to gut out the DX12/SM6 portions.

The following code is a solution for UE4 to set Niagara Render Mesh at runtime, all credit goes to the very helpful @SouryGame.
You will need to use c++. For those that don’t use/know c++ I can share a Plugin for use with Blueprints, but you’ll still need Visual Studio installed and working for UE4 in order to build the plugin.

Solution for use with Editor:
This following code works in the editor only, due to DuplicateObject function crashing while creating a new Niagara System in a packaged game. If anyone has a fix for this, I’d be interested to know. But it’s not important because we have another solution right after this.


///need to add "Niagara" to your build.cs dependencies.

///needed includes for your .cpp file:
#include "../Plugins/FX/Niagara/Source/Niagara/Classes/NiagaraSystem.h"
#include "../Plugins/FX/Niagara/Source/Niagara/Public/NiagaraMeshRendererProperties.h"

/////

UNiagaraSystem* UMyNiagaraFunctionLibrary::CreateNiagaraSystemWithMesh(UNiagaraSystem* SystemTemplate, UStaticMesh* NewMesh)
{
	UNiagaraSystem* System = DuplicateObject(SystemTemplate, GetTransientPackage());

	for (const FNiagaraEmitterHandle& EmitterHandle : System->GetEmitterHandles())
	{
		const UNiagaraEmitter* Emitter = EmitterHandle.GetInstance();
		for (UNiagaraRendererProperties* Renderer : Emitter->GetRenderers())
		{
			if (UNiagaraMeshRendererProperties* MeshRenderer = Cast<UNiagaraMeshRendererProperties>(Renderer))
			{
				for (FNiagaraMeshRendererMeshProperties& Mesh : MeshRenderer->Meshes)
				{
					Mesh.Mesh = NewMesh;
				}
			}
		}
	}

	return System;
}

Solution for use with a Packaged Game:
This works for editor and packaged game but will overwrite the input Niagara system meshes. So everytime you spawn that Niagara System it will use the meshes you last updated it with.

UNiagaraSystem* UMyNiagaraFunctionLibrary::CreateNiagaraSystemWithMesh(UNiagaraSystem* SystemTemplate, UStaticMesh* NewMesh)
{
	UNiagaraSystem* System = SystemTemplate;

	for (const FNiagaraEmitterHandle& EmitterHandle : System->GetEmitterHandles())
	{
		const UNiagaraEmitter* Emitter = EmitterHandle.GetInstance();
		for (UNiagaraRendererProperties* Renderer : Emitter->GetRenderers())
		{
			if (UNiagaraMeshRendererProperties* MeshRenderer = Cast<UNiagaraMeshRendererProperties>(Renderer))
			{
				for (FNiagaraMeshRendererMeshProperties& Mesh : MeshRenderer->Meshes)
				{
					Mesh.Mesh = NewMesh;
				}
			}
		}
	}

	return System;
}

You can also use this by Spawning a non-activated Niagara System. Get the System Asset from Spawned Niagara System, use the function code above to change the meshes, then you can Activate the System with Reset enabled and the meshes changes work! This way is useful if you don’t want to overwrite the original system meshes.

Lastly, if you just want to change/update the meshes in the editor and and save the mesh changes. You can just save the Niagara System asset in the content browser. The editor isn’t aware you changed the asset so you have to save the asset manually if you want the changes saved for your project.

1 Like

This might help.

1 Like