How to make Android Plugin for Unity: Take photo from camera and gallery
Capture and Share in-game moment is a very important feature of mobile game nowadays. During the making of Kingdom Reborn — Art of War and Penguin Fight we write a simple plug in for Unity which can take photo from camera and gallery to use in game.
Write the plugin with Android Studio
Create a project in Android Studio
Create a project with no activity, click next few times and you are ready to code
Add Unity’s Library to your Project
If your plugin wants to communicate with Unity, you have to add the Classes.jar file in
<Unity-install-directory>\Editor\Data\
PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes
to your project
This library contains the com.unity3d.player.UnityPlayer class which will be used in our plugin.
Copy Classes.jar to
<Your-Project-Dir>/app/libs
then add it as Library as shown below:
The UnitySendMessage function
The Java class com.unity3d.player.UnityPlayer has a static method UnitySendMessage which can be used in Java to pass data to script code.
This then calls back to the Unity code to deliver the message to the object in Unity’s Scene. We’ll name it KoiGameObject.
KoiGameObject has a Script attached to it: KoinCallBack
public class KoiCallBack : MonoBehaviour {//Plugin calls this function by UnitySendMessage to KoinGameObject
void KoiCamera_PickDone(string param)
{
Koi.getInstance().handleImage(param);
}//Plugin calls this function by UnitySendMessage to KoinGameObject
void KoiGallery_PickDone(string param)
{
Koi.getInstance().handleImage(param);
}}
The Koi Java Class
The plugin code is pretty straight forward, we have Koi class which can launch two Android activites: Camera and Gallery.
/**
* Open phone’s gallery
*/
public void launchGallery(Context context){
launchAndroidActivity(context,KoiGalleryActivity.class );
}
/**
* Start phone’s camera
*/
public void launchCamera(Context context){
launchAndroidActivity(context,KoiCameraActivity.class );
}
The Koi has sendMessageToKoiObject which is used to send message to a GameObject (named “KoiGameObject”) in Unity’s Scene
It also has setPluginData and getPluginData to store/return image data
public static void sendMessageToKoiObject(String method,
String message)
{
UnityPlayer.UnitySendMessage(Koi.KOI_GAMEOBJECT, method, message);
}/**
* Same as sendMessageToKoiObject, but use JSONArray as message
*/
public static void sendMessageToKoiObject(String method,
JSONArray parameters)
{
sendMessageToKoiObject(method, parameters.toString());
}/**
* Return the result to Unity
*/
public byte[] getPluginData(){
return pluginData;
}
/**
* Set the data result to return later
*/
public void setPluginData(byte[] data){
pluginData = data;
}
In KoiGalleryActivity class, after the user choose an image, we set image data to KoiPlugin to use later, then send message to KoiGameObject in Unity:
//The method name of script attached to KoiGameObject
public static final String KOI_GALLERY_CALL_BACK = "KoiGallery_PickDone";Bitmap bm;//the image which is chosen by user
….
JSONObject jso = new JSONObject();
try {
jso.put(“width”, bm.getWidth());
jso.put(“height”, bm.getHeight());
} catch (JSONException e) {
e.printStackTrace();
}
JSONArray jsa = new JSONArray();
jsa.put(jso);Koi.instance.setPluginData(byteArray);
Koi.sendMessageToKoiObject(KOI_GALLERY_CALL_BACK, jsa);
The KoiGallery_PickDone will be called in Unity, with the width and height of image passed as its parameters.
Build and Use the Plugin
Build the project using Gradle
You need to export you project as jar file in order to use in Unity.
Change the content of build.gradle as shown below
apply plugin: 'com.android.library'
android {
compileSdkVersion 24
buildToolsVersion "24.0.1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 24
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:24.1.1'
compile files('libs/classes.jar')
}
//task to delete the old jar
task cleanJar(type: Delete) {
delete 'release/KoiPlugin.jar'
}
//task to export contents as jar
task exportJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
rename('classes.jar', 'KoiPlugin.jar')
}
exportJar.dependsOn(cleanJar, build)
ReSync the project and you will have a new exportJar task in Gradle:
Execute the task and you will have KoiPlugin.jar in
<Your-Project-Dir>/app/release
Add KoiPlugin into Unity
Copy KoiPlugin.jar into
Assets\Plugins\Android
Because we have two Android activities for Gallery and Camera, we also need to describe them in Assets\Plugins\Android\AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.grepgame.test.koi">
<uses-sdk android:minSdkVersion="9"/><application>
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="unityplayer.UnityActivity"
android:value="true" />
</activity>
<activity android:name=
"com.grepgame.android.plugin.grplugin.KoiGalleryActivity"/>
<activity android:name=
"com.grepgame.android.plugin.grplugin.KoiCameraActivity"/>
</application>
<uses-permission android:name=
"android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>
(If your Unity project does not have Android folder and AndroidManifest.xml, just create them)
Use KoiPlugin in Unity
Create an emty GameObject in your Scene, name it KoiGameObject. From this scene, use the following code to open the Gallery
//instance of Koi plugin
AndroidJavaObject androidObject;//Reference to Unity Player
AndroidJavaObject unityObject;
AndroidJavaClass unityClass =
new AndroidJavaClass(“com.unity3d.player.UnityPlayer”);unityObject =
unityClass.GetStatic<AndroidJavaObject>(“currentActivity”);
AndroidJavaClass androidClass =
new AndroidJavaClass
(“com.grepgame.android.plugin.grplugin.Koi”);androidObject =
androidClass.GetStatic<AndroidJavaObject>(“instance”);}public void openGallery()
{
//call the launchGallery method of Koi Plugin
androidObject.Call(“launchGallery”, unityObject);
}
The instance of Koi Java class in Plugin will be created. It then launch the Gallery for user to pick, if an image is picked, the plugin will callback to KoiGallery_PickDone.
At this point, we know that the Plugin is holding the actual image data, we can get this data by calling
androidObject.Call<byte[]>(“getPluginData”)
Source code
Sorry for the long post, all source code of this post can be found at: