$30 off During Our Annual Pro Sale. View Details »

Game Development with Unity from an Android Point of View @DevFestNantes

Game Development with Unity from an Android Point of View @DevFestNantes

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

October 22, 2019
Tweet

More Decks by Julien Salvi

Other Decks in Programming

Transcript

  1. Game Development
    with Unity from an
    Android Point of View
    Place your screenshot here
    Julien Salvi

    View Slide

  2. Android addict since Froyo
    Punk rock & IPA!
    You can find me at @JulienSalvi
    Julien Salvi
    Senior Android Engineer @ Innovorder

    View Slide

  3. × Game Development on Android
    × Building Unity Plugins
    × Unity from Android Studio
    × What’s next?

    View Slide

  4. 1.
    Game Development on
    Android
    A global overview

    View Slide

  5. Place your screenshot here
    Major Game engines for Android

    View Slide

  6. “More than 50% of
    new mobile games
    are made with unity!”

    View Slide

  7. Place your screenshot here
    Trusted by many studios

    View Slide

  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 Asset Store!
    Game development on Android
    Building Android apps with Unity

    View Slide

  9. × OpenGL and Vulkan support
    × Bridge to native platforms
    × Android Studio project export
    × Java and Kotlin support
    Game development on Android
    Building Android apps with Unity

    View Slide

  10. 2.
    Building Unity Plugins
    Android to the rescue!

    View Slide

  11. Building Unity plugins
    Game Developers with Unity
    × Build apps with C# scripts
    × Control the rendering pipeline
    × Cross-platform shader compilation
    Bring the best experience at a high frame rate!

    View Slide

  12. For our fellow Unity
    developers

    View Slide

  13. “Building Plugins
    for Unity”
    13

    View Slide

  14. × Build your plugin using Java/Kotlin or C/C++
    × Android plugins might be: .jar, .aar or .so
    × Add Java or Kotlin classes directly into your Unity Project
    Build an Android Plugin for Unity

    View Slide

  15. Android Plugin for Unity
    For example let us build a player plugin for Unity
    Call player methods from Unity

    View Slide

  16. Unity
    They are best friends! Let’s eat some
    C# and C++!
    16

    View Slide

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

    View Slide

  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

    View Slide

  19. Calling a JAVA/Kotlin object from Unity
    AndroidJavaObject localMediaPlayer = null;
    using (AndroidJavaClass javaUnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
    using (currentActivity = javaUnityPlayer.GetStatic("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("getTrackCount");
    currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(() => {
    // Do some work on Android UI thread
    localMediaPlayer.Call("doOnMainThread", true);
    }));
    }
    }
    }

    View Slide

  20. Function inside your plugin
    Define the plugin function in your Unity script
    extern "C" {
    float FooPluginFunction ();
    }
    C/C++ Plugin
    [DllImport ("PluginName")]
    private static extern float FooPluginFunction ();

    View Slide

  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

    View Slide

  22. JNI method for calling a method in a Java class
    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, "", "()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

    View Slide

  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
    };
    Sending event to the native surface for low-level rendering

    View Slide

  24. Set a native callback and dispatch an event to the native plugin from Unity
    // 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);

    View Slide

  25. Your C++ method in your JNI plugin
    JNIEXPORT jstring JNICALL Java_js_NativePlugin_getHiString(JNIEnv * env, jobject obj) {
    return env->NewStringUTF("Bonjour DevFest Nantes ! Hope you have fun");
    }
    C/C++ from Java or Kotlin

    View Slide

  26. From Kotlin
    C/C++ from Java or Kotlin
    external fun getHiString(): String
    From Java
    public native String getHiString();
    From Kotlin
    init {
    System.loadLibrary("sample-jni")
    }
    From Java
    static {
    System.loadLibrary("sample-jni");
    }

    View Slide

  27. × Support available from 2018.2
    × Add your files in a dedicated folder in
    the Asset Folder
    × Build with Gradle only
    × Use the AndroidJavaObject class to
    call methods in your plugin
    Building Unity Plugins
    Using Java or Kotlin source files as plugins

    View Slide

  28. × Enable Custom Gradle Templates
    property on the Player window
    × Override the generated
    mainTemplate.gradle file
    × You can also provide your own
    settings.gradle file
    Building Unity Plugins
    Add Gradle dependencies to your Unity project

    View Slide

  29. 3.
    Unity from Android
    Studio
    Your turn Android devs!

    View Slide

  30. That’s what we want!

    View Slide

  31. × Export your Unity project with
    Gradle or IL2CPP as Build
    System
    × Enable Symlink Sources if you
    have Java or Kotlin source files
    Unity from Android Studio
    Exporting a Unity Project

    View Slide

  32. × Have a full control of the build
    workflow
    × Easily add Android code
    × Easy library management
    × Modify generated code
    Unity from Android Studio
    Exporting a Unity Project

    View Slide

  33. UnityPlayerActivity overview
    public class UnityPlayerActivity extends Activity {
    protected UnityPlayer mUnityPlayer; // don't change it, 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();
    }
    }

    View Slide

  34. Override the UnityPlayerActivity
    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
    }
    }

    View Slide

  35. 4.
    What’s Next?
    \ (•◡•) /

    View Slide

  36. What’s next?
    Linux support is coming soon
    Better Gradle integration
    Better performances

    View Slide


  37. And that’s it?

    View Slide


  38. Of course not!

    View Slide


  39. Unity as a LiBrary!

    View Slide

  40. What’s next?
    Unity as a Library
    × Available with Unity 2019.3
    × Add Unity content (AR/VR, 2D/3D
    games) directly to your Android apps
    × Proper library integration

    View Slide

  41. View Slide

  42. public class MainUnityActivity extends OverrideUnityActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    goBackBtn.setOnClickListener(v -> { showMainActivity(); });
    sendMsgBtn.setOnClickListener(v -> {
    UnitySendMessage("Cube", "ChangeColor", "yellow");
    });
    finishBtn.setOnClickListener(v -> { finish(); });
    }
    }
    Override the OverrideUnityActivity

    View Slide

  43. What’s next?
    Unity as a Library limitations
    × Fullscreen rendering only
    × Only one instance of the Unity runtime
    is supported
    × You may need to adapt your plugins to
    work properly

    View Slide

  44. What’s next?
    Unity as a library
    01
    02
    03
    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-nat
    ive-ios-android-apps.685195/
    Using Unity as a library in native iOS/Android apps
    https://forum.unity.com/threads/integration-unity-as-a-library-
    in-native-android-app.685240/
    Integration Unity as a library in native Android app

    View Slide


  45. Eh! What about
    Android from a Unity
    Point of view?
    random person in the audience - right now

    View Slide


  46. I was about to
    tell them!

    View Slide

  47. What’s next?
    Android from a Unity Point of View
    × Easy to build on Android
    × Graphic libs support (OpenGL/Vulkan)
    Easy compat with ShaderLab
    × No need to dig into the Android
    documentation

    View Slide

  48. What’s next?
    Android from a Unity Point of View
    × How it is implemented under the hood
    × Building UI components
    × Integrating Unity games into Android apps…
    but Unity as a library is coming

    View Slide

  49. Want to know more?
    https://developer.android.com/game
    Android Game Development
    https://medium.com/@cinemur/73ec7e83dd5c
    ExoPlayer for building powerful VR players on Cardboard and GearVR
    https://docs.unity3d.com/Manual/PluginsForAndroid.html
    Building Unity Plugins for Android

    View Slide

  50. THANKS!
    Have fun with Android and Unity!
    Any questions?

    View Slide