Plugins - Pro/Mobile-Only Feature
Unity has extensive support for C, C++ or Objective-C based Plugins. Plugins allow your game code (written in Javascript, C# or Boo) to call into native code libraries. This allows Unity to integrate with other middleware libraries or legacy game code.
Note: Plugins are a Pro-only feature. For desktop builds, plugins will work in standalones only. They are disabled when building a Web Player for security reasons.
In order to use a plugin you need to do two things:
- Write a plugin in a C based language and compile it.
- Create a C# script which calls functions in the plugin to do something.
So the plugin provides a simple C interface. The script then invokes the functions exposed by the plugin.
Here is a very simple example:
The C File of a Minimal Plugin:
float FooPluginFunction () { return 5.0F; }
A C# Script that Uses the Plugin:
Desktop
using UnityEngine;
using System.Runtime.InteropServices;
class SomeScript : MonoBehaviour {
// This tells unity to look up the function FooPluginFunction
// inside the plugin named "PluginName"
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
void Awake () {
// Calls the FooPluginFunction inside the PluginName plugin
// And prints 5 to the console
print (FooPluginFunction ());
}
}
Android
using UnityEngine;
using System.Runtime.InteropServices;
class SomeScript : MonoBehaviour {
// This tells unity to look up the function FooPluginFunction
// inside the plugin named "PluginName"
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
void Awake () {
// Calls the FooPluginFunction inside the PluginName plugin
// And prints 5 to the console
print (FooPluginFunction ());
}
}
Desktop
Building a Plugin for Mac OS X
If you are building a plugin for Mac OS X, you have to create a bundle. The easiest way to do this is using XCode. Use and select the Bundle - Carbon/Cocoa Loadable Bundle.
If you are using C++ (.cpp) or Objective-C (.mm) to implement the plugin you have to make sure the functions are declared with C linkage to avoid name mangling issues.
extern "C" {
float FooPluginFunction ();
}
Building a Plugin for Windows
Plugins on Windows are DLL files with exported functions. Practically any language or development environment that can create DLL files can be used to create plugins.
Again, if you use C++, declare functions with C linkage to avoid name mangling issues.
Using your plugin from C#
Once you have built your bundle you have to copy it to folder. Unity will then find it by its name when you define a function like this:
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
Please note that PluginName should not include the extension of the filename. Be aware that whenever you change code in the Plugin you will have to recompile scripts in your project or else the plugin will not have the latest compiled code.
Deployment
For cross platform plugins you have to include both .bundle (for Mac) and .dll (for Windows) files in Plugins folder. Once you have placed your plugins in the Plugins folder there is no more work required on your side. Unity automatically picks the right plugin for the right deployment platform and includes it with the player.
Android
Building a Plugin for Android
To build a plugin for Android, you first need the Android NDK. Please familiarize yourself with the steps how to build a shared library.
If you are using C++ (.cpp) to implement the plugin you have to make sure the functions are declared with C linkage to avoid name mangling issues.
extern "C" {
float FooPluginFunction ();
}
Using Your Plugin from C#
Once you have built your shared library you have to copy it to folder. Unity will then find it by its name when you define a function like this:
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
Please note that PluginName should not include the prefix ('lib') nor the extension ('.so') of the filename. It is recommended to wrap all native code methods with an additional C# code layer. This code could check Application.platform and call native methods only when running on the actual device and return mockup values when running in the Editor.
Deployment
For cross platform plugins, your Plugins folder may include plugins for several different platforms (i.e. libPlugin.so for Android, Plugin.bundle for Mac and Plugin.dll for Windows). Unity automatically picks the right plugin for the right deployment platform and includes it with the player.
Using Java Plugins
The Android plugin mechanism also allows Java to be used to enable interaction with the Android OS. Java code can unfortunately not be called directly from C#; only native code can call Java, so a native plugin is necessary to 'translate' the calls.
Building a Java Plugin for Android
There are several ways to create a Java plugin. What they have in common is that you will end up with a .jar file containing the .class files for your plugin. One way is to start off with downloading the JDK, then compile your .java files from command line with javac to create .class files and package them into a .jar with the jar command line tool. Another way is to use Eclipse IDE together with the ADT.
Using Your Java Plugin from Native Code
Once you have built your Java plugin (.jar) you have to copy it to folder. Unity will package your .class files together with the rest of the Java code, and then call it through something called Java Native Interface (JNI). JNI works both ways; calling native code from Java, and interacting with Java (or the JavaVM) from native code.
To find your Java code from the native side you need to have access to the Java VM. Fortunately that is quite easy; just add a function like this to your C(++) code:
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* jni_env = 0;
vm->AttachCurrentThread(&jni_env, 0);
}
This is all that is needed to start using Java from C(++). Completely explaining JNI is somewhat beyond the scope of this document, but usually it includes finding the class definition, resolving the constructor (<init>) method and create a new object instance, as shown here:
jobject createJavaObject(JNIEnv* jni_env) {
jclass cls_JavaClass = jni_env->FindClass("com/your/java/Class"); // find class definition
jmethodID mid_JavaClass = jni_env->GetMethodID (cls_JavaClass, "<init>", "()V"); // find constructor method
jobject obj_JavaClass = jni_env->NewObject(cls_JavaClass, mid_JavaClass); // create object instance
return jni_env->NewGlobalRef(obj_JavaClass); // return object with a global reference
}
Extending the UnityPlayerActivity Java Code
With Unity Android it is also possible to extend the regular UnityPlayerActivity (primary Java class the Unity Player on Android). An application can, by creating a new Activity which derives from UnityPlayerActivity, override any and all of the basic interaction between Android OS and Unity Android.
To do that first locate the shipped with Unity Android. It is found under the installation folder (usually (on Windows) or (on Mac)) in a folder called . Then add that file to the classpath used to compile the new activity. The resulting .class file(s) should be compressed into a .jar file and placed under . As the manifest dictates which activity to launch it's also necessary to create a new AndroidManifest.xml. The AndroidManifest.xml should also be placed under .
The new activity could look like OverrideExample.java:
package com.company.product;
import com.unity3d.player.UnityPlayerActivity;
import android.os.Bundle;
import android.util.Log;
public class OverrideExample extends UnityPlayerActivity {
protected void onCreate(Bundle savedInstanceState) {
// call UnityPlayerActivity.onCreate()
super.onCreate(savedInstanceState);
// print debug message to logcat
Log.d("OverrideActivity", "onCreate called!");
}
public void onBackPressed()
{
// instead of calling UnityPlayerActivity.onBackPressed() we just ignore the back button event
// super.onBackPressed();
}
}
And this is what the matching AndroidManifest.xml would look like:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product">
<application android:icon="@drawable/app_icon" android:label="@string/app_name">
<activity android:name=".OverrideExample"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Examples
Desktop
Simplest Plugin
This is a basic example of a project and a plugin that only do basic operations (prints a number, prints a string, adds two floats and adds two integers). Check this example if this is your first time learning plugins in Unity.
The project can be found here.
This project includes both Windows and Mac project files.
Midi Plugin
A complete example of the Plugin interface can be found here.
This is a complete Midi plugin for OS X which uses Apple's CoreMidi API. It provides a simple C API and a C# class using the C API. The C# class contains a high level API, with easy access to NoteOn and NoteOff events and their velocity.
Texture Plugin
An example of how to assign image data to a texture from C++ directly to OpenGL (note that this will only work when Unity is using an OpenGL renderer). This example includes both XCode (for Mac) and Visual Studio (for Windows) project files. The plugin with accompanying Unity project can be found here.
Android
Native Plugin Sample
A simple example of the use of native code plugin can be found here
This sample demonstrates how C code can be invoked from a Unity Android application. The package includes a scene which displays the sum to two values, calculated by the native plugin. Please note that you will need the Android NDK to compile the plugin.
Java Plugin Sample
An example of the use of Java code can be found here
This sample demonstrates how Java code can be used to interact with the Android OS and how C++ creates a bridge between C# and Java. The package includes a scene which displays a button that when pressed fetches the application cache directory, as defined by the Android OS. Please note that you will need both the JDK and the Android NDK to compile the plugins.
The same example but based on a prebuilt JNI library to wrap the native code into C# can be found here
More Information
Mono Interop with native libraries.
P-invoke documentation on MSDN.
Page last updated: 2011-01-31



