📜 ⬆️ ⬇️

Unity3D - writing plugins for Android

Foreword


Hello!
Here are instructions on how to extend the capabilities of Unity3D in working with Android applications. In other words, we can write the necessary functionality for Android in Eclipse as a library in the Java programming language, export it to .jar and use it in Unity3D. Basically, they write what is missing in the capabilities of Unity3D - such things as turning on / off the flashlight or long-term vibration

image

What we need



')

Sources


Unity3d project
Eclipse project

Android



Writing the Android library for Unity3D is no different from writing a regular Android library for anything. Just to get started, you need to take another library specifically for this from Unity - to do this, go to the folder where we installed it (usually C: / ProgramFiles ), then go along this path Unity \ Editor \ Data \ PlaybackEngines \ androidplayer \ bin \ classes.jar , and copy the library to a convenient place for you.

Create a project in Eclipse: click “File” - “Project” - “Android Application Project” - “Next”, and then enter the name of the object. Suppose we need to write a project that can turn an Android device light on and off (there is no such function in Unity3D initially). Then call the project UnityTorch . Package Name for the project will be com.izaron.habr.unitytorch . Then several times click "Next", until we reach the name of our activity. We call it UnityTorchActivity (the name of the main class depends on it), then click “Finish”

We have a project created. Now move the classes.jar library about which you spoke above to the libs folder

Open UnityTorchActivity.java in the src folder, it looks like this
package com.izaron.habr.unitytorch; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class UnityTorchActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_unity_torch); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.unity_torch, menu); return true; } } 


In order for our plugin to work with Unity3D, our activity must inherit from UnityPlayerActivity
Change the file to this state
 package com.izaron.habr.unitytorch; import com.unity3d.player.UnityPlayerActivity; import android.os.Bundle; public class UnityTorchActivity extends UnityPlayerActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } } 


As we see, nothing happens here. Now we need to write a class Torch.java , which is responsible for the flashlight and contains functions that enable / disable it. A little google, and we have this class ready
Hidden text
 package com.izaron.habr.unitytorch; import com.unity3d.player.UnityPlayerActivity; import android.content.pm.PackageManager; import android.hardware.Camera; import android.hardware.Camera.Parameters; public class Torch { private Camera cam; //   public UnityPlayerActivity activity; //      public boolean isEnabled; // -  public Torch(UnityPlayerActivity activity) { this.activity = activity; isEnabled = false; cam = Camera.open(); //      } public boolean hasTorch() { //      ,   false return (activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)); } public void turnLightOn() { if(hasTorch()) { isEnabled = true; cam = Camera.open(); Parameters p = cam.getParameters(); p.setFlashMode(Parameters.FLASH_MODE_TORCH); //  cam.setParameters(p); cam.startPreview(); } } public void turnLightOff() { if(hasTorch()) { isEnabled = false; cam.stopPreview(); cam.release(); } } public boolean enabled() { return isEnabled; } } 



Attention! There may be an error related to activity.getPackageManager () . To fix it in the AndroidManifest.xml file, you can change the line “android: minSdkVersion =" 8 "" to "android: minSdkVersion =" 9 "", and everything will be OK

The final part - we make a copy of the Torch in the main class
 package com.izaron.habr.unitytorch; import com.unity3d.player.UnityPlayerActivity; import android.os.Bundle; public class UnityTorchActivity extends UnityPlayerActivity { public Torch torch = new Torch(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } } 


Unity3d


We create the project in Unity3D
All plug-ins for Android must be stored in the Assets / Plugins / Android folder, otherwise the unit will not “see” the plug-in - create this folder. There you can throw AndroidManifest.xml, jar-files of libraries, res folder for storing resources

Now we are going back to the project in Eclipse, click: right-click on the project in the left section - “Export” - “JAR file” - “Next” - write the path to Assets / Plugins / Android of our Unity-project - “Finish”

We create directly in Unity in the same folder AndroidManifest.xml - not directly in the editor, but in the Explorer, or in the IDE (Visual Studio, MonoDevelop)

We write in this file

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.izaron.habr.unitytorch" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="9" /> <application android:label="@string/app_name" android:icon="@drawable/app_icon"> <activity android:name="com.izaron.habr.unitytorch.UnityTorchActivity" android:configChanges="keyboardHidden|orientation" 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> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.WRITE_SETTINGS"/> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> </manifest> 

What you need to change is the name of the package, android: name of the activity and uses-permisson's

We don’t copy the manifest from the Eclipse project, we don’t need it

Now we need to create a small “wrapper” above the library - we create two files: TorchActivity.cs and Torch.cs

TorchActivity.cs (don't forget about the package name)
 using UnityEngine; using System.Collections; public static class TorchActivity { #if UNITY_ANDROID && !UNITY_EDITOR public static AndroidJavaClass activityClass = new AndroidJavaClass("com.izaron.habr.unitytorch.UnityTorchActivity"); public static AndroidJavaClass unityActivityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); public static AndroidJavaObject activityObj = unityActivityClass.GetStatic<AndroidJavaObject>("currentActivity"); #else public static AndroidJavaClass activityClass; public static AndroidJavaClass unityActivityClass; public static AndroidJavaObject activityObj; #endif } 


Torch.cs
 using UnityEngine; using System.Collections; public static class Torch { #if UNITY_ANDROID && !UNITY_EDITOR private static AndroidJavaObject torchObj = TorchActivity.activityObj.Get<AndroidJavaObject>("torch"); #else private static AndroidJavaObject torchObj; #endif public static bool HasTorch() { if (Application.platform == RuntimePlatform.Android) return torchObj.Call<bool>("hasTorch"); else return false; } public static bool Enabled() { if (Application.platform == RuntimePlatform.Android) return torchObj.Call<bool>("enabled"); else return false; } public static void TurnLightOn() { if (Application.platform == RuntimePlatform.Android) torchObj.Call("turnLightOn"); } public static void TurnLightOff() { if (Application.platform == RuntimePlatform.Android) torchObj.Call("turnLightOff"); } } 


Why do we need two fields activityClass and activityObj? Through activityObj we can call UnityTorchActivity methods, and static functions can only be called via activityClass. Such a small (and mean for newbies) nuance
Otherwise, everything is pretty transparent - the launch of functions outside the Android platform does not lead to anything good

Conclusions - writing plug-ins for Android for Unity3D is not very widespread practice, which is why there are almost no articles about this area. I hope that brought clarity to this question. Thanks for attention!

Sources


Unity3d project
Eclipse project

Source: https://habr.com/ru/post/226987/


All Articles