iOS編はこちら

C# からJavaコードの呼び出し

public class HogeClass {
  private static string JAVA_CLASS_NAME = "com.hoge.JHogeClass";

  public void Hoge() {
    using (AndroidJavaClass plugin = new AndroidJavaClass(JAVA_CLASS_NAME)) {
      plugin.CallStatic("hogeNative");
    }
  }
}
  • usingはC#の文法で、ガベコレ対策(ガベコレが走るまでJava側のリソースを保持し続けてしまうのを防止するため)
package com.hoge;

public class JHogeClass {
  public static void hogeNative() {
  }
}
  • Javaのコードはコンパイルして.jarを作り、Assets/Plugins/Android/以下に配置すると、Buildでリンクされる。

  • とりあえずJava側のstaticメソッドの呼び出しだけ試した

コールバック

  • C#からJavaにメソッドを渡して呼び返してもらう、ということはできないようで、UnityPlayer.UnitySendMessageというのを使う:
package com.hoge;

import com.unity3d.player.UnityPlayer;

public class JHogeClass {
  public static void hogeNative() {
    UnityPlayer.UnitySendMessage("オブジェクト名", "HogeCallback", "message");
  }
}
  • シーンに存在する「オブジェクト名」のGameObjectにメソッドを送ることができる
    • そのため、コールバックを受け取るオブジェクトはMonoBehaviourを継承したGameObjectで、シーンに配置され、一意の名前を持っている必要がある
    • C#からJavaに対してコールバックして欲しい対象のオブジェクト名を渡して、それに対してUnitySendMessageをするといいかもしれない
  • メッセージを介して渡せるのは文字列だけなので、複雑な結果を渡したい場合にはシリアライズ/デシリアライズする必要がある
  • コンパイルするにはUnityのクラス情報が入った.jarファイルが必要(Macの場合/Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/release/bin/classes.jarにある)

アクティビティの取得

Java側でAndroidのAPIを呼び出す場合、ActivityやContextが欲しい時が多い。それを取得するにはC#で、

public class HogeClass {
  public void fuga() {
    using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
      using (AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) {
        ...
      }
    }
  }
}
  • Unityから起動されるアプリのActivityはUnityPlayerか、カスタマイズしている場合その派生クラスだと思うけど、そのstaticなcurrentActivityフィールドに格納されているらしい。

参考