How to Create Android Plugins for Unity

This tutorial will go through how you can create Android .aar libraries and use them with C# in Unity.

First make sure you have the latest Android Studio installed. Then use the SDK Manager to install the required SDKs and tools.
Navigate to Tools -> SDK Manager and install the latest Android SDK Platform available.

Android SDK

Then on the SDK Tools subpage install these:
• Android SDK Tools
• Android SDK Build-tools
• Android SDK Platform-tools

Now let's create a new project in Android Studio.
Navigate to File -> New... -> New Project.
Select the option: Add No Activity

Android Studio

In the next popup configure your plugin by giving it a name and a package name. The package name will be used within C# code to reference your plugin.

Configure Project

Next navigate to File -> Project Structure
Here you will need to configure the project build properties. Select the latest 'Build Tools Version' you have installed and configure the compatibility fitting to your project.

Project Properties

Next create a new Java Class. Right click on your package name under /app/java/ and click on New -> Java Class.

Add Class

Then give your new class a name and write the functionality within the class. For this example we create a static method that uses the Android Random class to generate a random number. This static method will then be called from C#.

package com.vuopaja.unityplugintutorial;
import java.util.Random;

public class RandomNumber
{
     public static int Generate(int maxValue)
     {
         Random random = new Random();
         return random.nextInt(maxValue);
     }
}

Next we need to configure the build.gradle file for the app module. First we need to change the build type to library instead of an application. This change configures gradle to output an aar file when building. Also the default config has some properties that need to be removed when building a library, like the applicationId. More info about this can be found here.

// Change build type to library instead of an application.
// apply plugin: 'com.android.application'
apply plugin: 'com.android.library'

// Remove unneccessary properties
defaultConfig {
     minSdkVersion 16
     targetSdkVersion 28
}

We add the following snippet to the build.gradle. It includes a task exportAAR that copies the build result .aar file to a location we specify (build/release/ in this case). Also we rename the file to RandomNumber.aar for convenience. We also create a task deleteExistingAAR that deletes an existing version of the plugin before building a new one. Then we declare that the exportAAR task depends on the deleteExistingAAR task and build so that when we run the task we first delete the previous version, then build the project and finally copy the result to our release folder.

task exportAAR(type: Copy) {
     from('build/outputs/aar/')
     into('build/release/')
     include('app-release.aar')
     rename('app-release.aar', 'RandomNumber.aar')
}

task deleteExistingAAR(type: Delete) {
     delete 'build/release/RandomNumber.aar'
}

exportAAR.dependsOn(deleteExistingAAR, build)

Here you can see the complete build.gradle after all of our changes:

apply plugin: 'com.android.library'

android {
     compileSdkVersion 28
    
     defaultConfig {
         minSdkVersion 16
         targetSdkVersion 28
     }
    
     task exportAAR(type: Copy) {
         from('build/outputs/aar/')
         into('build/release/')
         include('app-release.aar')
         rename('app-release.aar', 'RandomNumber.aar')
     }
    
     task deleteExistingAAR(type: Delete) {
         delete 'build/release/RandomNumber.aar'
     }
    
     exportAAR.dependsOn(deleteExistingAAR, build)
    
     buildTypes {
         release {
             minifyEnabled false
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
         }
     }
    
     compileOptions {
         sourceCompatibility = 1.6
         targetCompatibility = 1.6
     }
    
     buildToolsVersion = '29.0.2'
}

dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation 'androidx.appcompat:appcompat:1.0.2'
     testImplementation 'junit:junit:4.12'
     androidTestImplementation 'androidx.test.ext:junit:1.1.0'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

Next we just need to sync gradle and Android Studio should prompt you to do so after you edit the build.gradle file.
Then we need to remove the contents of res folder in the project view. Otherwise the contents would be included in the .aar file and Unity build would fail. We also need to remove references to those res files from the AndroidManifest.xml. This is located at /app/manifests/AndroidManifest.xml. Remove the application tag and all of its contents.

Res Folder

Now we find our exportAAR task in the gradle view and run it.

Gradle View

With that we have created a plugin that is ready to be imported to Unity. If you want to examine the created .aar file you can rename it to have an .zip extension and uncompress it. The file contains the plugin in .jar format and the manifest in .xml among other things.

So let's hop over to Unity. First we add the generated RandomNumber.aar file to our project into /Assets/Plugins/Android/ folder.
Next we create a C# script in our Unity project that uses the newly created plugin. Here is sample code showing how we can call the static method that we implemented in the Java code.

using UnityEngine;

public class AndroidPluginExample : MonoBehaviour
{
     UnityEngine.UI.Text text;
     AndroidJavaClass javaClass;
    
     void Start ()
     {
         // Get a reference to our Java class
         javaClass = new AndroidJavaClass("com.vuopaja.unityplugintutorial.RandomNumber");
        
         // We setup a simple UI in Unity Editor to display the result on button click.
         // Here we just get references to UI objects and set up a listener.
         text = GetComponentInChildren();
         var button = GetComponentInChildren();
         button.onClick.AddListener(onUiButtonClicked);
     }
    
     void onUiButtonClicked()
     {
         // Call the static method using the java class reference.
         // We call the Generate method that returns an integer and give the maximum range as an argument
         int randomNmb = javaClass.CallStatic("Generate", 100);
         text.text = randomNmb.ToString();
     }
}

Now we just build the android Unity project as usual and see that our plugin works.

All of the code in this example can be found in a GitHub repository.

In this tutorial we went through how to call Java methods from C# but if you want to know how to work in the other direction check out the tutorial on How to Implement Android Java Callbacks to Unity C#.

Thanks for reading! If you have any questions click here to send us email.