[JAVA] Comment créer un plug-in natif Unity (version Android)

Aperçu

Si vous souhaitez rendre le SDK développé pour Android compatible avec les applications Unity, vous devez créer un plug-in pour relier les applications SDK et Unity. Il existe plusieurs façons d'implémenter des plugins natifs pour Android, mais cet article présentera une méthode qui hérite de UnityPlayerActivity. Veuillez vous référer à Common Edition pour l'implémentation des parties communes avec le plug-in pour iOS.

Côté plug-in

BaseNativeActivity BaseNativeActivity est une classe qui hérite de UnityPlayerActivity. Il agit comme un wrapper en appelant en son nom les méthodes des classes définies dans le SDK, telles que Sample et SampleLifecycle.

BaseNativeActivity


public class BaseNativeActivity extends UnityPlayerActivity {
    public static final void setCallbackGameObjectName(String name) {
        SampleUnityListener.getInstance().setCallbackGameObjectName(name);
    }

    @Override
    protected void onStart() {
        super.onStart();
        SampleLifecycle.onStart(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        SampleLifecycle.onResume(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        SampleLifecycle.onPause(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SampleLifecycle.onDestroy();
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        return super.onPrepareOptionsMenu(menu);
    }

    public void start(String sampleCode) {
        Sample.getInstance().start(this);
    }

    public void doSomething() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Sample.getInstance().doSomething()
            }
        });
    }

    public int getScore() {
        return Sample.getInstance().getScore();
    }

    public String getSomeText() {
        return Sample.getInstance().getSomeText();
    }

    public boolean isAvailable() {
        return Sample.getInstance().isAvailable();
    }
}

SampleUnityListener SampleUnityListener est une classe pour transmettre le rappel du côté SDK vers le côté Unity. Il implémente SampleListener, une classe d'écouteur définie du côté du SDK.

SampleUnityListener


public class SampleUnityListener implements SampleListener {
    private static final Sample sample = Sample.getInstance();
    private static SampleUnityListener instance;
    private String callbackGameObjectName;

    public synchronized static SampleUnityListener getInstance() {
        if (instance == null) {
            instance = new SampleUnityListener();
            sample.setListener(instance);
        }

        return instance;
    }

    public final void setCallbackGameObjectName(String name) {
        callbackGameObjectName = name;
    }

    @Override
    public void onStatusChanged(SampleStatus status) {
        if (callbackGameObjectName != null) {
            String statusIndex = String.valueOf(status.ordinal());
            UnityPlayer.UnitySendMessage(callbackGameObjectName, "_Sample_didStatusChange", statusIndex);
        }
    }
}

build.grade Ceci est un exemple de build.gradle. En plus du SDK lui-même (SampleSDK- *. Jar), classes.jar est inclus dans le répertoire libs pour importer des classes telles que UnityPlayerActivity, mais il est exclu car il n'est pas nécessaire au moment de la construction. De plus, comme il est nécessaire de résoudre le nom du côté Unity, minify est également défini sur false.

build.gradle


apply plugin: 'com.android.library'

android {
    compileSdkVersion 26
    buildToolsVersion "25.0.3"
    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:26.+'
}

android.libraryVariants.all { variant ->
    variant.outputs.each { output ->
        output.packageLibrary.exclude('libs/classes.jar')
        output.packageLibrary.exclude('libs/SampleSDK-*.jar')
    }
}

À propos de build

Pour Android Studio, vous pouvez créer un aar à partir de Build-> Make Module. L'aar construit doit être placé sous Assets / Plugins / Android dans le projet Unity. Aussi, veuillez vous référer à ici pour la méthode d'acquisition de classes.jar utilisée au moment de la compilation.

Côté unité

Sample_Android.cs Sample_Android.cs est une classe qui implémente ISample, et en accédant à la classe (BaseNativeActivity) implémentée côté plug-in, application Unity et SDK Nous allons faire le pont.

Sample_Android.cs


using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

public class Sample_Android : ISample {
    private Sample sampleGameObject;
    private SampleEventListener listener;
    private static AndroidJavaObject androidInstance;

    public Sample_Android(Sample sampleParent) {
        sampleGameObject = sampleParent;

        InitAndroidInstance();
        CreateListenerObject();

        if (sampleParent.androidSampleCode != null) {
            Start(null);
        }
    }

    private void CreateListenerObject() {
        listener = sampleGameObject.gameObject.AddComponent<SampleEventListener>();

        using (AndroidJavaObject activityObject = GetCurrentActivity()) {
            activityObject.CallStatic("setCallbackGameObjectName", sampleGameObject.gameObject.name);
        }

        listener.SetNativeParent(this);
    }

    public void Start(string sampleCode) {
        using (AndroidJavaObject activityObject = GetCurrentActivity()) {
            if (sampleGameObject.androidSampleCode != null) {
                activityObject.Call("start", sampleGameObject.androidSampleCode);
            } else if (sampleCode != null) {
                activityObject.Call("start", sampleCode);
            }
        }
    }

    public void DoSomething() {
        using (AndroidJavaObject activityObject = GetCurrentActivity()) {
            activityObject.Call("doSomething");
        }
    }

    public int GetScore() {
        using (AndroidJavaObject activityObject = GetCurrentActivity()) {
            return activityObject.Call<int>("getScore");
        }
    }

    public SampleStatus GetStatus() {
        SampleStatus status = SampleStatus.Unavailable;

        using (AndroidJavaObject statusObject = androidInstance.Call<AndroidJavaObject>("getStatus")) {
            string statusName = statusObject.Call<string>("name");

            if (statusName.Equals("Unavailable")) {
                status = SampleStatus.Unavailable;
            } else if(statusName.Equals("Available")) {
                status = SampleStatus.Available;
            }
        }

        return status;
    }

    public string GetSomeText() {
        return androidInstance.Call<string>("getSomeText");
    }

    public bool IsAvailable() {
        using (AndroidJavaObject activityObject = GetCurrentActivity()) {
            return activityObject.Call<bool>("isAvailable");
        }
    }

    public AndroidJavaObject GetCurrentActivity() {
        using (AndroidJavaClass playerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
            return playerClass.GetStatic<AndroidJavaObject>("currentActivity");
        }
    }

    protected static void InitAndroidInstance() {
        using (AndroidJavaClass sampleClass = new AndroidJavaClass("com.sdk.Sample")) {
            androidInstance = sampleClass.CallStatic<AndroidJavaObject>("getInstance"); 
        }
    }
}

AndroidManifest.xml Ceci est un exemple d'Android Manifest placé sous le projet Assets / Plugins / Android of Unity. L'activité native de base mentionnée ci-dessus est décrite.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player"
	  android:installLocation="preferExternal"
	  android:theme="@android:style/Theme.NoTitleBar"
	  android:versionCode="1" android:versionName="1.0">
  <supports-screens android:smallScreens="true"
		    android:normalScreens="true"
		    android:largeScreens="true"
		    android:xlargeScreens="true"
		    android:anyDensity="true" />
  <application android:label="@string/app_name" android:debuggable="false">
    <activity android:name="com.sample.plugin.BaseNativeActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
    </activity>
  </application>
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

Proguard Si vous souhaitez définir des paramètres tels que le fait d'éviter Minify pour certaines classes, créez proguard-user.txt et placez-le sous Assets / Plugins / Android of Unity project, et il sera automatiquement exporté en tant que projet Android. Cela sera reflété.

proguard-user.txt (exemple)


-keepattributes *Annotation*
-keepattributes Signature
-keep class com.sample.sdk.** {
  public <fields>;
  public <methods>;
}

-keep class com.sample.plugin.** {
    public <fields>;
    public <methods>;
}

-dontwarn com.sample.sdk.**

Structure du répertoire

Placez les éléments suivants sous Assets / Plugins / Android du projet Unity selon vos besoins. -Corps SDK (pot / aar)

référence

https://docs.unity3d.com/ja/540/Manual/PluginsForAndroid.html

Recommended Posts

Comment créer un plug-in natif Unity (version Android)
Comment écrire React Native Bridge ~ Version Android ~
Comment créer un plug-in Jenkins
[Android] Comment créer un fragment de dialogue
[Unity] J'ai essayé de créer un plug-in natif UniNWPathMonitor en utilisant NWPathMonitor
Comment faire un pot ombré
Comment créer un lecteur de musique Android imposant
Comment utiliser Struts2 * Spring Framework (plugin Spring) Version de juin 2017
Comment abaisser la version java
Java - Comment créer JTable
Comment vérifier la version JSF
[Rails] Comment faire des graines
[Version 2020] Comment envoyer un e-mail à l'aide d'Android Studio Javamail
Comment créer une application à l'aide de Tensorflow avec Android Studio
Comment "évider" une vue sur Android
Comment créer un pilote JDBC
Comment créer un écran de démarrage
Comment faire un projet Maven
Comment créer un tableau Java
Android: Comment gérer "Impossible de déterminer la version Java à partir de '10 .0.1 '"
Comment créer un résumé de calendrier Java
[Android] Comment gérer les thèmes sombres
Comment détecter les conflits de microphone sur Android
Comment créer un robot Discord (Java)
Comment ajouter des informations sur la version de l'application aux informations Sentry
Comment créer une application avec un mécanisme de plug-in [C # et Java]
Comment utiliser ExpandableListView dans Android Studio
[Android] Comment convertir une chaîne de caractères en resourceId
[Android] Comment détecter le changement de volume (= pression sur le bouton de volume)
Comment réduire l'image de Spring Boot Docker
Utilisation du composant d'interface utilisateur natif avec React Native (version Android)
Créer un logiciel qui reflète l'écran Android sur un PC 1
Comment rendre la logique de vérification en double plus lisible
Comment créer un JRE léger pour la distribution
Comment utiliser le protocole NFS version 2 avec Ubuntu 18.04
Comment exécuter NullpoMino 7.5.0 sur la version 64 bits d'Ubuntu 20.04.1
[Java] Comment rendre plusieurs boucles for uniques
Comment créer un plugin Vagrant que vous avez appris lorsque vous avez forké et publié vagrant-mutagen
Comment rendre une image partiellement transparente avec le traitement
[Android Studio] Comment changer TextView en n'importe quelle police [Java]
Comment faire un test unitaire Java (JUnit & Mockito & PowerMock)
Comment organiser les informations pour rationaliser l'apprentissage de la programmation
[Ruby] Comment utiliser rbenv (la version `x.x.x 'n'est pas installée)
Comment faire fonctionner JavaScript sur une page spécifique
[Android Studio] [Java] Comment réparer l'écran verticalement
Comment utiliser Truth (bibliothèque d'assertions pour Java / Android)
[Android] Comment obtenir la langue de réglage du terminal
Un débutant en développement d'applications a essayé de créer une application de calculatrice Android
Comment empêcher editTextPreference de Android PreferenceFragmentCompat de se rompre
Installez MySQL 5.6 sur CentOS6 [Comment spécifier la version]
Comment transmettre des informations de pixels d'image de manière native depuis Unity
Comment télécharger une ancienne version d'Apache Tomcat