Spawning multiple meshes in niagara with predefined position/orientation

Hey everyone,

Im having a bit of trouble with something and i am hoping someone here might be able to give me some insight. I have a mesh that has been fractured in 3ds max and i have each piece imported into the engine as a static mesh. I want to spawn each piece as a niagara particle so i can blast them apart. The issue comes from the fact that when i spawn them, i want them to have the same initial position and orientation they were in when i exported them. If i set the pivots for all the objects to the same location, they will line up, however when they spin they will rotate around the pivot point and move strangely. They will also scale based on the pivot as well. If i export each mesh with the pivot in the center, it will rotate/scale properly, but then all of the particles will just be clumped together in the same location when i spawn them. Does anyone have any idea how to solve this?

Is this a viable way to do this? I dont really want to use geom caches because there are many objects being spawned. I have not tried skel meshes yet, can they be played/controlled via niagara?

There is a brute force method im thinking about but i only want to use that as a last resort. I could put the pivot at the center of each piece, then manually write down each xyz offset and then mirror that for each piece in the editor. That sounds like a nightmare of manual work though… :skull:

Hey,

May be these snippets of scratch pads could give you some ideas?
https://dev.epicgames.com/community/snippets/L2B/unreal-engine-niagara-spawn-particles-in-custom-positions

Also, not long ago I saw a breakdown of this effect by @Tzupi
They’re creating arrays of transforms, mesh IDs and height from the ground for all static meshes in the level with the actor tag in construction script and then using this information in Niagara to seamlessly swap static meshes to mesh particles. May be this could be useful in your case if you want to swap meshes to particles instead of spawning particles right away?

Hmm, i will look into it but i dont think this would work for me. Im not using any static meshes or blueprints, its purely a niagara system.

I did actually manage to get it working by using my brute force method. Its a pain to setup so it would be great to figure out a better way, but at least it gives me a path forward.

Here is the breakdown. I made all the pieces in 3ds max using tyflow and set all the pivots to the center of each piece. I made a quick script in 3ds max that outputs the pivot offsets for each piece and i export all the pieces as static meshes.

In niagara i created a set param and set it to position array and linked it to the meshID of each piece. Then i manually copy/pasted the offsets for every piece into the array.

There is one important detail that i spent a lot of time trying to figure out. Unreal uses a left hand coordinate system, while 3ds max uses a right hand coordinate system. This means that the Y axis from 3ds max to unreal is flipped! Once i figured that out, everything lined up.

This works, but as you can imagine there is a LOT of manual work. I had 25 pieces and each piece needs 3 floats to create a vector, that’s 75 manual copy/paste actions for one asset. If there is some way to batch edit the values that would be awesome but i don’t know of any way to do that. Possibly a scratchpad with some custom code i can copy/paste…

Thanks!

I managed to get it working in scratchpad! It dramatically speeds up the entire workflow. Now this method is actually viable! Here is the setup…

It stores all the vectors as an array and then maps each line to the mesh index. The first line is index0, the second is index1 etc. This way i can copy/paste the entire block of vectors that are output from my 3ds max script. I might make a mini tutorial later. This may be useful to others who want a cheap way to destroy a mesh. This could also be combined with sim stages to do a PBD physics simulation if you want all the pieces colliding and interacting. Lots of possibilities!

// === EXACT positions provided by user ===
static const float POS_DATA[] = {

//Paste X/Y/Z vectors here.

};
// Safety cap to avoid out-of-bounds if PosCount is wrong
static const int MAX_POS = 999;
// ========================================

// Niagara inputs: Index (int), PosCount (int)
// Niagara output: OutPosition (float3)

float3 result = float3(0.0, 0.0, 0.0);
int count = clamp(PosCount, 0, MAX_POS);

if (Index >= 0 && Index < count)
{
    int baseIndex = Index * 3;
    result = float3(
        POS_DATA[baseIndex + 0],
        POS_DATA[baseIndex + 1],
        POS_DATA[baseIndex + 2]
    );
}

OutPosition = result;
1 Like

That’s amazing! Thanks a lot for sharing.