Custom structs and enums in Niagara

After creating some Enums and Custom structs (where some of members in those structs are of types of those enums) in editor, I assigned them in Edit->Project options->plugins->Niagara to be visible in Niagara. After recompiling everything was fine. Both structs and enums were visible inside Niagara and I can freely used them. But after whole editor restarting, editor crashes instantly. After debugging, it looks that order of loading those types is wrong. Editor tries to load structs at first place (and it doesn’t know about those Enum definitions at that time and crashes). Huge bug. After manually change those members in structs to be just integers, editor started normally. After that I created User parameter in Niagara of type of that struct. And it works fine in Niagara but problem is when some of that fields in user parameter has to be referenced by blueprint. Inside editor, those structs are exposed as overrides and all members can be setup. Problem is runtime. Setting of Niagara variable is strictly typed (every supported type has its own function) so passing whole struct as user parameter is not possible (that should be fixed… if struct members are all of supported types what is the problem to iterate over them and set them all?) But I also didn’t find a way to reference those variables separately. Usually user parameter of type lets say int is set up by calling function SetNiagaraVariable(int) where for variable name you define string like User.MyInt if MyInt is name of your user parameter. But if MyInt is member of MyStruct and whole struct is set as user parameter I didnt find a way to reference it. Tried with User.MyStruct.MyInt but at runtime nothing happens. Tried with User.MyInt and with MyStruct.MyInt but nothing worked. Is it a bug or am I missing something?

Thanks in advance

hello,do you konw how to solve this problem now?I meet the same now!

There is the ability to pass Objects and Structs into Niagara systems, but they won’t be readable.

To pass readable data into a Niagara system, it seems you need to use one of the built-in data interfaces.

If you open up the Niagara system and open the User Parameters tab, then click the + icon and go into Make New → Data Interface and pick Vector Array.

Name your user parameter TestVectors and the type will be Niagara Data Interface Array Float 3

To access Test Vectors, create a new Niagara module script (or scratchpad module) and in the Map Get node, click the + icon and go into Make New → Data Interface and pick Vector Array.

Name the attribute TestVectors and then drag off the Map Get pin to see the various functions under Vector Array such as Add, Length and most importantly Get.

You can then Get vectors from TestVectors and assign the data to other attributes in the Map Set node of the module script, so you have complete functionality.

For iteration, right click and find the Parameter Map For node and assign the Length of the Vector Array to the Iteration Count of the Map For, then use the Parameter Map For Current Index node to provide the current index to the Get function of the Vector Array.

Go back to the Niagara system that includes the module, click on the module within the emitter, and you will see the TestVectors module input in the details panel.

Drag the TestVectors user parameter from the User Parameters tab over to the details panel, and drop it onto the value of the TestVectors module input. This will link the user parameter to the module input.

Within blueprint, after you spawn the Niagara system using for example Spawn System Attached, then drag off the Return Value pin and find the Niagara Set Vector Array node.

Create your array of vectors with whatever data you like, and then wire that into the Array Data pin.

Finally, set the Override Name to TestVectors

Now your vector data can be passed from blueprint to any module script within any Niagara system.

1 Like

But it doesnt work with User defined structures. That was complaining about If you have structure of several different types inside ie. FVectors, FRotation user ENums defined for Niagara, etc. there is no way to pass whole structure (even if it is properly declared in Niagara section of project) but you have to link each struct member through predefined interface, which is nightmare, especially if your struct contains other structs as memebers. Modern GPUs kernels can do much heavier tasks than those asked. What is the problem to implement a IInterface to pass a whole buffer (esspecially if its size is const, which is 99% case when we are dealing with structures of const fields).??? In Niagara module, extracting from that buffer also should not be a problem as it has defined that User structure which would be content of the buffer, so by simple counting of sizes of its members each field is extracted to coresponding Niagara user parameter. This interface can also provide the atomicity of whole transaction where members of structure can not change as transaction is in progress. With current implementation, where user has to parse each structure member and pass it to Niagara through its coresponding interface doesent provide atomicity on whole structure. User is responsible to provide proper mechanisms which would guarantie atomicity of whole operation over whole structure…