Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Game Development with Unity from an Android Poi...

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
Tweet

More Decks by Julien Salvi

Other Decks in Programming

Transcript

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

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

    Unity from Android Studio • What’s next?
  3. 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
  4. OpenGL ES and Vulkan support Bridge to native platforms Android

    Studio project export Java and Kotlin support
  5. • Build apps with C# scripts • Control on the

    rendering pipeline • Cross-platform shader compilation Bring the best experience at a high frame rate!
  6. 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
  7. For example, let us build a player plugin for Unity.

    ➔ Call player methods (Java/Kotlin or C++) from Unity. Android Plugin For Unity
  8. 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
  9. 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
  10. extern "C" { float FooPluginFunction (); } C/C++ Plugin [DllImport

    ("PluginName")] private static extern float FooPluginFunction ();
  11. 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
  12. 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
  13. 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 };
  14. // 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);
  15. 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
  16. Enable Custom Gradle Template property on the Player window Override

    the generated mainTemplate.gradle file You can also provide your own settings.gradle file
  17. Export your Unity project with Gradle or IL2CPP as Build

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

    Android code Easy libraries management Modify generated code
  19. 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
  20. 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
  21. • Available with Unity 2019.3 • Add Unity content (AR/VR,

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

    the Unity runtime is supported ◆ ➔ You may need to adapt your plugins to work properly
  23. https://blogs.unity3d.com/2019/06/17/add-features-powered-by- unity-to-native-mobile-apps Unity as a Library https://forum.unity.com/threads/using-unity-as-a-library-in-native-i os-android-apps.685195/ Using Unity

    as a library in native iOS/Android apps https://forum.unity.com/threads/integration-unity-as-a-library-in-n ative-android-app.685240/ Integration Unity as a library in native Android app
  24. https://developer.android.com/game https://medium.com/@cinemur/73ec7e83dd5c Android Game Development ExoPlayer for building powerful VR

    players on Cardboard and GearVR https://docs.unity3d.com/Manual/PluginsForAndroid.html Building Unity plugins for Android Want to know more? https://blogs.unity3d.com/2019/06/17/add-features-powered-by- unity-to-native-mobile-apps Unity as a Library