How to pass enum in function?

I’m trying to create a node on a blueprint using
.cpp

#include “EdGraphSchema_K2_Actions.h”

void UMakeBlueprintNodeBPLibrary::AddNodeToBlueprint(UEdGraph* ParentGraph, const FVector2D Location, EK2NewNodeFlags Options)
{
FEdGraphSchemaAction_K2AddEvent::SpawnNode(ParentGraph, Location, Options);
}

.h
void AddNodeToBlueprint(class UEdGraph* ParentGraph, const FVector2D Location, EK2NewNodeFlags Options);

build.cs
PrivateDependencyModuleNames.AddRange(
new string[]
{
“CoreUObject”,
“Engine”,
“Slate”,
“SlateCore”,
“UnrealEd”,
“KismetCompiler”,
“AssetRegistry”,
“BlueprintGraph”,
// … add private dependencies that you statically link with here …
}
);

Builds fine. “EK2NewNodeFlags” colorizes as a known entity in both .h and .cpp.
Try to build in Unreal:
“.h(35): Error: Unable to find ‘class’, ‘delegate’, ‘enum’, or ‘struct’ with name ‘EK2NewNodeFlags’”
Tried #include “EdGraphSchema_K2_Actions.h” in .h file, same error. What am I doing wrong?

Hi Fibulator,

Try just putting enum class EK2NewNodeFlags; in the .h file rather than the #include - I notice that’s done in the UE source code in a few places…

“.h(35): Error: Unable to find ‘enum’ with name ‘class’”

You can’t use that enumeration in a UFUNCTION since it’s not declared with the UENUM macro. If you declare a function and skip the UFUNCTION macro it should work fine (as in like standard C++).

1 Like

But since it has to be a UFUNCTION, how do I work around this?

I don’t even set the enumerator anywhere, is there a “null” or “zero” option?
How do I pass the “none” option in the function call?

Enums just translate to Bytes, so it should be easy to cast any value to one, eg:

uint8 myKludgeEnum=0;
CallFunctionThatNeedsFlags(blah,blah,(EK2NewNodeFlags)myKludgeEnum);
1 Like

Why does it have to be a UFUNCTION? You haven’t really said what you’re trying to do other than “I’m trying to create a node on a blueprint” and I’ve never seen blueprint used to modify a graph in this way before. Usually you either make a blueprint callable function or create a custom K2 node to make something that can be placed onto the graph. Not scripts that modify the graph for you.

“Not scripts that modify the graph for you.”
That’s exactly what I’m trying to do. I’m trying to modify the graph by adding a node to it, such as “Add Triangle To Mesh”

I’m exposing this “add Node to graph” function as a node itself. Why? Because I have to fight tooth and nail to get any command to work in c++… it takes me 6-12 hours to get each command to work. I spend at least 3 hours of that every day reloading VS because intellisense says there’s “10,484 errors” and just breaks randomly. I’ve spent 4 days on this and managed to get a whopping 2 lines of code to work. /endRant

But that’s why it has to be a UFUNCTION, as that’s how it makes the function Blueprint callable.

In short: I’m trying to make an addon that will read Geo nodes from .Blend file, and create a Geometry Script graph of the equivalent.

Alright, well there’s nothing that you can do about the enumeration. It’s not exposed to reflection so it can’t be exposed directly to blueprint.

Option 1) Don’t include it as a parameter of the UFUNCTION. Given how you’re using it you can probably make a reasonable assumption about what it’s value should be globally in all cases. It looks like it controls behavior to select or jump the view to the new node, which makes sense when making one but if you have a script making multiple it doesn’t make as much sense. So you could remove it from your function and hard code in the None value.

Option 2) As RecourseDesign points out, it’s basically just an integer. You can have your function take a integer or byte and cast that to the enumeration. It’s looks like it’s a bitwise value so that makes it tougher to match up the values.

Option 3) Make you’re own enum that is blueprint accessible that has the same values as the NewNodeFlags. At least then you can include it in your function and add all the bitflag markup so that the blueprint UI does all the hard work for you. In native you’d still have to cast it.

Personally, out of those options, I’d go with option 1.

Thanks.
It appears to be the wrong command, as there’s no way that I can see to even specify the type of node I’m trying to spawn.

For the life of me I can’t figure out the C++ command to add a node (Add Triangles to Mesh, for example) to a graph in a blueprint. You wouldn’t happen to be able to help with that? Been bashing my head into a wall for 12+ hours.

I only know of one that lets you do it at blueprint compile time since that’s the how custom k2 nodes can act as macros to replace themselves with a different set of nodes. But that requires a compiler context variable that you don’t have (and only creates them temporarily to boot).

I wouldn’t be surprised if there isn’t one that let you do it dynamically like you’re trying to do. Not that there isn’t one, but I’ve never had reason to find it.

It’s just for the editor. Making an addon for devs.
But I know there’s a command that adds nodes to graphs… which is executed every time you add one to the graph… :sweat_smile: Just gotta find it, and figure out how to use it properly.
Kinda surprised no one has made a Blender Geometry nodes to Unreal Geometry script convertor addon…

After days of fumbling around I’m pretty sure this is the solution:

class UBlueprintNodeSpawner* Spawner;|

UK2Node_CallFunction NodeClass;|
NodeClass.SetFromFunction();|
Spawner->NodeClass = NodeClass;

But “setFromFunction” requires a “UFUNCTION” variable, and I have no idea the syntax to pass that through.

Say, for example the Ufunction I want to spawn is “static UBlueprint* CreateBlueprint”, what’s the syntax? I’ve tried just the function name, with quotes, with &&, etc.

First problem is that a UFunction is a property you have to get from the UClass.
Second problem is that that problem is irrelevant because you’re assigning the wrong thing to the spawner. Right now you’re trying to assign an instance to TSubclassOf which wants a class. So you'd assign it UK2Node_CallFunction::StaticClass().

You probably shouldn’t even bother with the spawner beyond looking at the implementation of UBlueprintNodeSpawner::SpawnEdGraphNode. I don’t see any reason you couldn’t do all of that on your own, directly. Just omit the things you don’t need like the PostSpawnDelegate (since you’ll know the type and how you want it configured).

There’s a specific spawner for functions: UBlueprintFunctionNodeSpawner | Unreal Engine Documentation

I didn’t see it earlier, because it’s a subnode of FieldNode spawn. -_-

This is what I have so far:
UFunction* Reference;
Reference->FindFunction(“Create Blueprint”);
class UBlueprintFunctionNodeSpawner* Spawner;
Spawner = Spawner->Create(Reference, nullptr);
FVector2D Slerp;
Slerp.Set(0.f, 0.f);
FBlueprintActionMenuItem Action;
Action = FBlueprintActionMenuItem::FBlueprintActionMenuItem(Spawner);
Action.PerformAction(Graph, nullptr, Slerp, false);

But I get “reference is not initialized”
I tried “Invoke” on Spawner, but it requires “bindings” and I haven’t the tiniest clue how to set those.

“Action Menu Item” is the “wrapper” we’re supposed to use… but still can’t quite figure it out.

Thanks for thanking the time to help a noob out… been 25+ years since I’ve touched C++.

Please provide syntax. I have no idea how to " So you'd assign it UK2Node_CallFunction::StaticClass()."

Tried:
UFunction* Reference;
UClass* Refer = UK2Node_CallFunction::StaticClass();
Reference = Refer->FindFunctionByName(“Create Blueprint”);
class UBlueprintFunctionNodeSpawner* Spawner;
FVector2D Slerp;
Slerp.Set(0.f, 0.f);
FBlueprintActionMenuItem(Spawner->Create(Reference, nullptr)).PerformAction(Graph, nullptr, Slerp, false);

But get error:LNK2019 unresolved external symbol “__declspec(dllimport) public: __cdecl FBlueprintActionMenuItem::FBlueprintActionMenuItem(class UBlueprintNodeSpawner const *)” (_imp??0FBlueprintActionMenuItem@@QEAA@PEBVUBlueprintNodeSpawner@@@Z) referenced in function “public: static void __cdecl UMakeBlueprintNodeBPLibrary::AddNodeToBlueprint(class UEdGraph *)” (?AddNodeToBlueprint@UMakeBlueprintNodeBPLibrary@@SAXPEAVUEdGraph@@@Z) GeoNodesToGeoScript

Three pieces of advice, and please take these as the constructive feedback they are intended:

  1. if you haven’t done C++ in a while, maybe it’s worth brushing up on that before trying to attack a problem like this.
  2. I don’t know how long you’ve been working with Unreal, but maybe you need to solve some easier problems and work up to what you really want to accomplish.
  3. Again I would suggest you ignore the menu item and function node spawner entirely except for looking at UBlueprintNodeSpawner::SpawnEdGraphNode and duplicating that code. It seems like it’s the basics of what you’re trying to do much more directly that what you’re trying.

Sorry if any this sounds harsh, I don’t mean it to be. But I’ve got to tap out at this point.

Thanks. But there’s no reason to “do other stuff first”, since this will be the only time I’m using C++ for anything… and wouldn’t even be doing that if there were any other way.

" UBlueprintNodeSpawner::SpawnEdGraphNode and duplicating that code."
Ahh, duplicating the code. I kept looking and there was no function “SpawnEdGraphNode” in documentation, or callable. I didn’t think to check internally.

That may be helpful.

If not, I’ll hit up fiverr and see if I can get some real help. Anyway, thanks.

Thanks, I found that code hidden internally. It looks like what I need, but I still have no idea what “Bindings” are, how to create them, or what they should be. Any suggestions?