Embedded Unity within Android App

Run a piece of unity from within a native android app.

In this blog I will save you some time (I assume you have the basic knowledge in Unity and Android development) and will guide you throw the steps of doing it. The main Idea is to take the Unity project and use it as a library in the native android app. Hold tight.

Step 1 : Create a Unity Project

Open Unity desktop application and create a new project. (I worked on Unity 5.5.0f3 but it should work on any version). Do your nifty unity stuff here as you like.

Step 2 : Support Android Back Button

Add an object, and attach the next script to it. In unity the back android button is not supported by default. So we add a script for it.

public class SupportBackScript : MonoBehaviour {
void FixedUpdate(){
if (Application.platform == RuntimePlatform.Android)
{
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
}
}
}

Step 3 : Export your Project

  • File → Build Settings
  • Select your scene
  • In platform section select Android
  • Change Texture to ETC2
  • Change Build System to Gradle
  • Click on player setting button → In Inspector tab → other setting add your package name under Bundle Identifier (see image below)
  • Mark Export and export

This will export your Unity project to Android one.

Step 4 : Import this project to Android Studio

File → New → Import project → Select your export folder from step 3.
If Android Studio is asking about change the project to gradle select yes.

Step 5 : Convert this project to a Library project

  • Open the manifest and remove/comment out the intent code, we don’t want this application to act like an app, just as library.
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.LAUNCHER"/>-->
<!--<category android:name="android.intent.category.LEANBACK_LAUNCHER" />-->
<!--</intent-filter>-->
  • Open the module gradle file, locate next line:
apply plugin: 'com.android.application'

And change to:

apply plugin: ‘com.android.library
  • Build the project, and take the AAR file aside.
    aar file should be located in: PROJECT_FOLDER\build\outputs\aar

Step 6 : Build your native Android app and use above aar file as library

  • Create your Native android app.
  • Add a new module from above aar file
    File → New Module → Import JAR/AAR Package, and select your aar file.
  • Make sure that in settings.gradle file there is next line:
include ':app', ':your_aar_file_name'
  • Add a dependency at your main module (app) to this aar
dependencies {
compile project(":your_aar_file_name")
compile fileTree(dir: 'libs', include: ['*.jar'])
...
}
  • Sync gradle

Step 7 : Solve gradle “Merger” issue if needed

After you will sync gradle as I told you in the end of step 6, you could get the next merger error:

Manifest merger failed with multiple error, see logs

This is because the merger is trying to use the icon and the theme of the library. Don’t be afraid, I’m here to to help you :) , add code as below to your main native application manifest file, to tells the merger to use this manifest icon and theme and not of other libraries.

  • adding to manifest tag xmlns:tools="http://schemas.android.com/tools"
  • adding to the application tagtools:replace="android:icon,android:theme"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.yourpackage.name">
<application
android:allowBackup="true"
tools:replace="android:icon,android:theme"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
...
</application>
</manifest>
  • Build your project again

Step 8 : Call the Unity Player Activity

Please note that the support for the Back button (Step 2) is a little bit tricky. The Application.Quit(); in the unity C# script is closing the UnityPlayerActivity and also the Activity that called her (too bad), so in order to handle it create a middle empty activity that in onCreate() call the UnityPlayerActivity intent like below.

import com.yourpackage.name.UnityPlayerActivity;
...
// DON'T CALL IT FROM YOUR MAIN ACTIVITY - SEE ABOVE INSTRUCTIONS!
Intent intent = new Intent(mContext, UnityPlayerActivity.class);
startActivity(intent);

Sooo that’s it. Long one but working.