FORCEINLINE ufunctions are not seen in BP

The next ufunction:

FORCEINLINE UFUNCTION(BlueprintCallable)  
	void setIsAiming(bool new_val) {setReplicatedFlagAt(1,new_val);}

Compiles and is usable in C++, but is not in BP. (doesn’t appear in the search, including context insensetive).
Similar signature function without FORCEINLINE flag is perfectly fine in BP.

Check out this thread. It looks like you can do it but you need to be a bit clever about it. I suspect the issue is related to the way UE4 links C++ to BPs. Getting that kind of stuff to work within standard C++ can require lots of tricks using templates and/or macros (usually with lots of # signs in there to “string-ize”). I’ve had to deal with that kind of thing myself so I can tell you that it’s pretty acceptable to have to work around the way Epic set it up.

Actually, yeah: if the function is inline then there wouldn’t be a way for the BP to call it. Since the BP isn’t C++ code there is no way to put the function inline. It needs to be a function call (with parameters pushed on the stack and all that) so the BP can call it (via the BP interpreter).

thanks, but the thread you have linked talks about a replicated UFUNCTION, while in my case it is a regular UFUNCTION.

I don’t think _Implementation is possible with this case

You can specify a Server-side RPC and call it from the server as a regular function. So you might be able to use the replicated UFUNCTION format to get what you want – even though you never call it from a client. I think calling a server RPC from the server is a direct call so there shouldn’t be any RPC overhead

There won’t be another way to do it. Like I said, the BP is not C++ code so there is nothing to compile the function into. This is part of why BPs will never be as fast as C++ (even with nativizing). BlueprintNative has an _Implementation too but UE4 generates the signature for you so I doubt it will work the same as the RPC method.

as i said already, this function has nothing to do with networking. i already call it from server functions so it acts just as a local function it is. the only problem is that i would like it to be inline to avoid another function call overhead (in C++ calls).

I only want to test that function here and there in BP although main logics are in C++, but it seems like i can’t do that while it’s FORCEINLINE.

I know what you said. I was suggesting a work-around that didn’t use the replication functionality but got you what you wanted.

As I said, BPs are not C++ code so they can’t inline a function. The compiler doesn’t compile blueprints, they are interpreted. Even if you got it to compile and show up in the editor, you wouldn’t gain any performance (except when the function was called from C++ directly, where it can be put inline by the compiler).

yeah, but i also use that ufunction in my C++ code, where the code does get compiled and inline boosts that performance.

actually that function is mainly for C++, and is declared ufunction for occasional minor uses in BP

So have two functions: one inline for C++ and one not-inline for BP. Then have the BP-callable function call the C++ function. That gets you the performance boost in C++ and makes the function visible to BPs.

that’s one approach i were thinking about, just curious if there is a way to prevent spaghetti code. (i have around 16 such functions and more to come)

The only other approach is to have a single function that is BP-callable and not inline.

The two-function way seems best to me. You may be able to figure out how to make it cleaner. Macros won’t work cuz the pre-processor needs to have them expanded so it can see the BP-callable stuff, but it won’t expand the macros.

There is one trick I’m using though. In the Build.cs file, I use Definitions.Add("X=1") so I can use X within a UCLASS declaration. You might be able to use that to define macros (never tried). Then the pre-processor may expand them for you. In that case you can set up macros that define both versions of the function. That would be cleaner.

Other than that, I suppose it would be cleaner to put all the C++ stuff in a base class and have another C++ class derived from that which holds all the BP-callable stuff. I guess “cleaner” is relative tho because I wouldn’t prefer this route.

thanks, ill see if i find something interesting out.

I have accidentally found a signature that works perfectly for both C++ and BP:

UFUNCTION(Category="C++", BlueprintPure) FORCEINLINE 
bool isAiming(){return ........your stuff....}

The secret is removing “BlueprintCallable”. It seems illogical but FORCEINLINE makes it callable anyway and you must not declare it callable explicitly, otherwise it will behave the opposite way.

@anonymous_user_64f7311b you might wanna look at the solution i have found