Calling platform specific code and back when game starts

Hi,
I just started thinkering with the amazing UE4, trying to getting through all the editor and the programming. I am an iOS and Android developer and I was considering using UE4 to develop part of native apps instead of resorting to plain OpenGL ES X.
For now I am focusing on iOS and then I will try to integrate everything with Android NDK.
What I need to do is to implement the following logic, for both Android and iOS:

  1. App launches
  2. Native interfaces are shown to the user
  3. App connects to a remote server via its own platform SDK methods
  4. Server replies
  5. If it’s ok, the Game launches, that is the UE4 “portion” of the app begins execution.

Now, researching on the topic I wasn’t able to find anything regarding how to launch the game part of the app after the app has started natively and users have taken some actions.
Looking at the UE source, I see that for iOS at least, the engine takes control of the AppDelegate (the entry point of the app), so I assume that if I wanted to override this behaviour and use the sdk libraries I’d have to rewrite quite a big part of the engine itself.

So my approach switched to leaving the app entry point to the engine and launch platform-specific methods as soon as the lifecycle of the game begins, that is:

  1. App launches
  2. UE launches, inits, sets up the environment etc
  3. Before the first level is presented, the native GUI is shown and the engine stays on hold
  4. Server replies using platform SDK methods
  5. UE resumes execution and presents the first level of the game

I found this amazing post on how to call a ViewController from the Engine, but the problem is that that topic refers to presenting a VC in response to a user action.
What I would need to do is to somehow “pause the engine loop” and use UIKit/Activities to manage user navigation before the game starts.
Problem is: I don’t know where should I intercept the lifecycle of the engine as a whole.

I created my GameMode class and set it as the default. I did override the BeginPlay method after calling Super::BeginPlay(). It compiles fine and I can see the iOS View, but I don’t know if I am doing it correctly or I am messing up the whole engine logic and I think that the engine is still running underneath while the display shows the iOS GUI.

After this wall of text, my questions are:

  1. In order to properly show a native GUI at launch, what class and which method should I look into? Or better, is there any doc/topic where it’s possible to have an idea of how the Engine (not only Actors) lifecycle works?

  2. Say I can successfully “pause/ignore/return” the engine loop how can I get back to the game from native code?

Thanks in advance and thanks for creating such a poweful thing - for free! :slight_smile:

Hi there!

Well, with such a plans there will be some engine digging and modifications I think :wink:

First - You’ve probably found it already but in IOSAppDelegate.cpp file there is a part with something we can call a main loop:

while( !GIsRequestingExit )
{
     if (self.bIsSuspended)
     {
          // .. Some stuff done when game is suspended
     }
    else
    {
        // .. All stuff when the game is running
    }
    [FIOSAsyncTask ProcessAsyncTasks];
}

and a method -(void)ToggleSuspend

I think this might be a good place to start for looking for a place to complately pause the engine.

For Android there is LaunchAndroid.cpp, also with while(!GIsRequestingExit) loop.

If there is a detailed documentation about the Engine flow? Well, I don’t think it is public, but it’s really easy to figure it out when You check those main loops. Try to follow what is happening with FAppEntry (PreInit, Init, Tick, SuspendTick, Shutdown).

Showing native GUI on iOS shouldn’t be a problem, with Android, well… I don’t have an experience with Android but I worry it will involve java and layouts.

Still… there might be an easier way… Why not to create an empty map where you wait for a response from the SDK and then load proper next map? You don’t have to hold the engine, it can simply do nothing!

Keep informing if you figure something out :slight_smile:

I recently started using native iOS functionality call from C and it’s pretty straightforward though I’m not sure about how to mix game and iOS content in one view (if someone has an example of that it would be interesting).

Hey!
OP here.
First of all thank you for your answers.
We did manage to integrate both Android and iOS into UE4 about one year ago.
Since someone seems interested in this topic this is how we did:

iOS

We wanted to use Storyboards and xibs to give a native UI feeling and to ease development, so we created an embedded framework (a library with resources) and we linked it to the UE code during compilation by thinkering with the buildscript (.cs) and ld. This was the hardest part, since there was no documentation available on how to link custom frameworks we had to dig quite deep into the source code.
In the native framework we created and compiled storyboards and bundles and we implemented a protocol that we called back from Blueprints and ultimately from C++.

The protocol was in charge of displaying and managing UIKit viewcontrollers from inside the framework.
With this approach we didn’t interfere with the engine lifecycle. We launched our viewcontrollers from the VC used by UE.

We did exactly as zompi suggested. The engine was “idle” in the background, ready to be shown when needed.

Android

As with iOS, we wanted to use Android Studio and all its goodies to develop the native part. In this case we had to use JNI methods through the Android NDK to intercept the Native Activity that the engine launches by default.
We compiled the UE game from Unreal Editor and then imported the resulting binary (the .obb file) and the c libs into Android Studio.
From there we rewrote the application flow by showing our own activity on app launch and starting the engine when needed from the JNI.

As far as the implementation goes, in our “game” we implemented an Actor that was in charge of communicating with Blueprints and platform specific code:

UCLASS()
class MYFRAMEWORK_API ANativeInterfaceActor : public ALevelScriptActor {
	
	GENERATED_BODY()
	
public:
	virtual void BeginPlay();
	
	UFUNCTION(BlueprintCallable, Category="Native Interface")
	void showMainMenu();
	
	UFUNCTION(BlueprintCallable, Category="Native Interface")
	void ExitFromEngine();
	
	UFUNCTION(BlueprintImplementableEvent, Category="Native Interface")
	void loginHasBeenCalled();

private:
	
#if PLATFORM_IOS
	iOSInterface* mIosInterface;
#endif
	
#if PLATFORM_ANDROID
	AndroidInterface* mAndroidInterface;
#endif
	
};

The iOS interface communicates with the Actor and uses UE [[IOSAppDelegate GetDelegate].IOSController to “intercept” the engine lifecycle.

IOSInterface.mm

@interface iOSInterface()

@end

@implementation iOSInterface {
	ANativeInterfaceActor* mHandler;
	
}

+ (iOSInterface*) GetDelegate {
	static iOSInterface* singleton = [[iOSInterface alloc] init];
	return singleton;
}

- (instancetype) initWithHandler:(ANativeInterfaceActor*) handler {
	self = [super init];
	
	if (self) {
		mHandler = handler;
		[MYFramework sharedInstance].delegate = self;
	}
	return self;
}

/**
 Presents the VC on the main thread
 */
- (void) presentControllerOnMainThread:(UIViewController*)viewController animated:(BOOL)animated{
	
	dispatch_async(dispatch_get_main_queue(), ^{
		[[IOSAppDelegate GetDelegate].IOSController presentViewController:viewController animated:animated completion: nil];
	});
}

- (void) showMainMenu {
	[self presentControllerOnMainThread:[[MYFramework sharedInstance] getMainMenu] animated:NO];
}

AndroidInterface needed to obtain the JNIEnv from the engine and then communicate with Android by means of JNI calls.
First we get a reference to the game activity, and then we control it from our class and from Java.
AndroidInterface.cpp

extern "C" void Java_com_epicgames_ue4_GameActivity_nativeSetGlobalActivityLocal(JNIEnv* jenv, jobject thiz) {

	LOGD("==========Initialized native activity===========");
	
	AndroidInterface::sGameActivity = jenv->NewGlobalRef(thiz);
}

I posted a working example in this post quite some time ago. If interested there you can find a sample Android project and some more detailed instruction on how to build everything.

Apologies if something is unclear but it has passed more than one year and things are quite blurry.

If more detail is wanted I see what I can get by diggin again into the code :slight_smile:
Hope this has been useful.

Hey there! I see that you have made some pretty amazing discovery and worked with ue4 as deep as the engine can go. I am trying to use a plugin for IOS but I don’t know how I can compile it with my game. I tried github ue4 and launcher ue4, but it doesn’t work. My project is BP only. Could you give me some hints please? Thanks in advance.