Game Development with Unity from an Android Point of View

Game Development with Unity from an Android Point of View

Developing mobile games with Unity has become more and more popular these years, and Unity developers often need to tackle OS specific challenges.

Through this talk you will discover how to work with Unity as an Android Developer. You will see how to build Unity plugins using the JNI and Java/Kotlin, which is the most efficient way to link Unity with the Android framework.

Every Unity project can be exported as an Android Studio project with a Gradle support. You'll also see how you can integrate Unity inside a native Android Java/Kotlin application, or how to get a full control of the build process so you can benefit from the best of both worlds.


Julien Salvi

August 09, 2019


  1. Game Development with Unity from an Android Point of View

    Julien Salvi
  2. Julien Salvi Android addict since Froyo Always looking for the

    best IPA! Twitter: @JulienSalvi Senior Android Engineer @ Innovorder
  3. • Game Development on Android • Building Unity Plugins •

    Unity from Android Studio • What’s next?
  4. 1 Game Development on Android A global overview

  5. None
  6. 50 More than 50% of new mobile games are made

    with Unity!
  7. None
  8. Available on Windows and Mac (soon on Linux) 2D, 3D

    games or AR/VR apps Fast prototyping, fast scripting Supporting most of the 3D and 2D formats Great Assets Store
  9. OpenGL ES and Vulkan support Bridge to native platforms Android

    Studio project export Java and Kotlin support
  10. 2 Building Unity Plugins Unleash the droid!

  11. • Build apps with C# scripts • Control on the

    rendering pipeline • Cross-platform shader compilation Bring the best experience at a high frame rate!
  12. None
  13. Building plugins for Unity

  14. Build your plugins using Java/Kotlin or C/C++ Android plugins might

    be : .jar, .aar ou .so Add Java or Kotlin files directly into your Unity Project (Gradle build only) Build an Android plugin for Unity
  15. For example, let us build a player plugin for Unity.

    ➔ Call player methods (Java/Kotlin or C++) from Unity. Android Plugin For Unity
  16. Let’s eat some C# and C++ Unity and JNI are

    best friends!
  17. J N I Java / Kotlin code C/C++ code Plugin

  18. public class PlayerBridge { private Context ctx; public PlayerBridge(Context ctx)

    {} public void addSubtitles(String path) {} public void doOnMainThread(boolean playWhenReady) {} public int getTrackCount() {} } Android Plugin for Unity
  19. AndroidJavaObject localMediaPlayer = null; using (AndroidJavaClass javaUnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))

    { using (currentActivity = javaUnityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) { localMediaPlayer = new AndroidJavaObject("my/plugin/vr/PlayerBridge", currentActivity); if (localMediaPlayer != null) { // Do some work with your java object outside the Android UI thread localMediaPlayer.Call("addSubtitles", subtitleURL); int count = localMediaPlayer.Call<int>("getTrackCount"); currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(() => { // Do some work on Android UI thread localMediaPlayer.Call("doOnMainThread", true); })); } } } Calling a JAVA/Kotlin object from Unity
  20. extern "C" { float FooPluginFunction (); } C/C++ Plugin [DllImport

    ("PluginName")] private static extern float FooPluginFunction ();
  21. Better performances when you call your Java plugin through the

    JNI Important: JVM loading jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* jni_env = 0; vm->AttachCurrentThread(&jni_env, 0); return JNI_VERSION_1_6; } Java and C/C++ Plugin
  22. JNIEXPORT jobject JNICALL Java_com_example_NativeClass_nativeMethod(JNIEnv* env) { jclass cls_JavaClass = env->FindClass("com/your/java/Class");

    // find class definition jmethodID mid_JavaClass = env->GetMethodID (cls_JavaClass, "<init>", "()V"); // find constructor method jobject obj_JavaClass = env->NewObject(cls_JavaClass, mid_JavaClass); // create object instance return env->NewGlobalRef(obj_JavaClass); // return object with a global reference } Java and C/C++ Plugin
  23. static void UNITY_INTERFACE_API OnRenderEvent(int eventID) { switch((GLEvent)eventID) { case Initialize

    : InitMediaSurface(); break; case Shutdown : mediaSurface->Shutdown(); mediaSurface = NULL; break; case Update: mediaSurface->Update(); break; case Resize: mediaSurface->ResizeTexture(); break; } } Java and C/C++ Plugin static void UNITY_INTERFACE_API OnRenderEvent(int eventID); enum GLEvent { Initialize = 0, Shutdown = 1, Update = 2, Resize = 3 };
  24. // Set the native callback from Unity _inptr_native_callback_delegate = Marshal.GetFunctionPointerForDelegate(NativeCallback);

    // Native method from the plugin CINEVR_AndroidNative_SetNativeCallback(_inptr_native_callback_delegate); Java and C/C++ Plugin // Get native callback from the plugin to queue for Unity's renderer to invoke IntPtr _renderFunc = CINEVR_AndroidNative_GetRenderEventFunc(); // Dispatch the event to native plugin GL.IssuePluginEvent(_renderFunc, GLEventType.Initialize);
  25. Added support in 2018.2 Add your files in a dedicated

    folder in the Assets folder Build with Gradle only Use the AndroidJavaObject class to call methods in your plugin
  26. Enable Custom Gradle Template property on the Player window Override

    the generated mainTemplate.gradle file You can also provide your own settings.gradle file
  27. 3 Unity from Android Studio Your turn Android devs!

  28. None
  29. Export your Unity project with Gradle or IL2CPP as Build

    System Enable Symlink Sources if you have Java or Kotlin source files
  30. Have a full control of the build workflow Easily add

    Android code Easy libraries management Modify generated code
  31. public class UnityPlayerActivity extends Activity { protected UnityPlayer mUnityPlayer; //

    don't change the name; referenced from native code @Override protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); getWindow().setFormat(PixelFormat.RGBX_8888); // <--- This makes xperia play happy mUnityPlayer = new UnityPlayer(this); setContentView(mUnityPlayer); mUnityPlayer.requestFocus(); } } UnityPlayerActivity overview
  32. public class OverrideExample extends UnityPlayerActivity { @Override protected String updateUnityCommandLineArguments(String

    cmdLine) { if (Utils.preferVulkan()) return Utils.appendCommandLineArgument(cmdLine, "-force-vulkan"); else if (Utils.preferES2()) return Utils.appendCommandLineArgument(cmdLine, "-force-gles20"); else return cmdLine; // let Unity pick the Graphics API based on PlayerSettings } } Override the UnityPlayerActivity
  33. 4 What’s next? \ (•◡•) /

  34. Linux support is coming soon Better Gradle integration Better performances

  35. None
  36. None
  37. None
  38. • Available with Unity 2019.3 • Add Unity content (AR/VR,

    2D/3D games) directly to your Android app • Proper library integration
  39. None
  40. ➔ Fullscreen rendering only ◆ ➔ Only one instance of

    the Unity runtime is supported ◆ ➔ You may need to adapt your plugins to work properly
  41. unity-to-native-mobile-apps Unity as a Library os-android-apps.685195/ Using Unity

    as a library in native iOS/Android apps ative-android-app.685240/ Integration Unity as a library in native Android app
  42. Android Game Development ExoPlayer for building powerful VR

    players on Cardboard and GearVR Building Unity plugins for Android Want to know more? unity-to-native-mobile-apps Unity as a Library
  43. Have fun with Unity and Android!