Any workaround to make Delegates bind successfully inside macros?

I was setting up GameSparks for one of our projects but I’m facing this issue where Unreal fails to bind if the UFUNCTION is inside a macro. Full AnswerHub post here: https://answers.unrealengine.com/questions/427611/unable-to-bind-delegate-1.html

Since GameSparks dont have support for Linux, I made a macro to strip out GameSparks features from Linux build. I modified the Build.cs file to add the definition.


if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Mac))
        {
            PublicDependencyModuleNames.AddRange(new string] { "GameSparks" });
            Definitions.Add("IS_GAMESPARKS_PLATFORM=1");
        }
        else
        {
            Definitions.Add("IS_GAMESPARKS_PLATFORM=0");
        }

Now in my classes Im wrapping all functions that require GameSparks using this macro.

Game Instance header file:


#if IS_GAMESPARKS_PLATFORM
UFUNCTION()
virtual void OnPlayerLogin(FGSAuthenticationResponse AuthenticationResponse, bool hasErrors);
#endif

Problem is with the above code. It compiles fine and I can launch the game but when it comes to binding this function Unreal fails to bind and this is the error:


Unable to bind delegate to 'OnPlayerLogin' (function might not be marked as a UFUNCTION)

If i remove IS_GAMESPARKS_PLATFORM macro then everything works perfectly. I thought this might be related to that specific macro so I used the below method but still the same error:


#if PLATFORM_WINDOWS || PLATFORM_MAC
UFUNCTION()
virtual void OnPlayerLogin(FGSAuthenticationResponse AuthenticationResponse, bool hasErrors);
#endif

In the end the problem is Unreal fails to bind delegates if its inside a macro :(. Im using Github Promoted branch. If there is a commit that fix this issue, I’ll be happy to merge it to my build.

Pretty sure UE4 reflection macros are just incompatible with preprocessor directives used in that way.

Anyway, switching in and out significant portions of code at compile time like that is generally not ideal. Instead why not implement it with classes and polymorphism? For example, define a base class that implements all common behaviour, then a derived class adding the GameSparks-only functionality. Then the only place you need to put compiler directives is at the point where you instantiate the class, and you choose based on platform which class to instantiate.

If you need to expose stuff to blueprints it’s a bit more work, but still doable. Just define the interface in the base class, but with no implementation. Then derive from it to implement GameSparks specific stuff.

But then how can I assign the Game Instance class at runtime? Separating the functionality between non-GameSparks and GameSparks is so far done only Game Instance class and I am only aware of assigning it in Project settings.

Off-topic question: Your FlexQuest looks very interesting (especially the Quest Tree editor). Good job buddy! :). You used Slate to create the editor?

Ah okay if this is in your game instance I guess config files would be the way to go. You can configure which class to use as your game instance through config files, and config files have a hierarchy which includes specific platforms. So you should be able to set up your default game instance class in DefaultEngine.ini, and then override it with a different class for specific platforms.

I’m afraid I haven’t used config files much myself so I can’t tell you exactly how, but see Config Setting at the bottom of this page, and info on config hierarchies is here.

Re: FlexQuest. Thanks. Yeah all editor side stuff is done in Slate. I’ve been away a couple of months so haven’t made any progress, but hopefully will get back onto it soon.

Hello and ,

I already posted on the Answerhub that created but I wanted to give an update here just in case anyone comes across this in the future. I’ve been able to reproduce the problem and have put in a bug report for the issue under the number UE-31627 as I believe it should be working.

Have a nice day!

Thank you Clark. Since I am using Github would you be kind to update if a commit to this issue is available? I’d be happy to merge it into my branch :slight_smile:

Sure thing. Once a fix has gone in and been merged into the release or master branch, I’ll notify you on the Answerhub post (as it’s linked to the Bug Report itself) of the commit that the fix is located in.

Awesome! :smiley: Looking forward to it :slight_smile: