Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
93
Help us understand the problem. What is going on with this article?
@YukiMiyatake

やはりUNITYでAndroidプラグインを作るにはAndroidJavaClassが便利だ

More than 1 year has passed since last update.

UNITYでスマホ用アプリを開発していると
どうしても、ネイティブ機能を使う必要が出てきます
ので、その時の言語バインディングには色んな方法あるので
メモ的に

C言語でバインド

AndroidであればNDKで soファイルを作りそれをリンクします
C言語ぶぶんはそれだけで あれがあれなので今回はヘッダのみ

c言語
extern "C" {
  const char* cfunk (int n);
} 
c#
[DllImport ("PluginName")]
private static extern const char* cfunc (int n); 

DllImportします。
これは iOSとのリンクするときも同じです
JavaやC#は リバースエンジニアリングが容易なので
セキュリティー関連等は あえてC言語で書く人も多いと思いますし
速度を重視したり、大量のメモリを使う場合等
C++を使う場面も多いと思います
が、C++なので当然 基本データ型しか使えません
string も当然使えないので char* 等で渡しましょう

Javaでバインド(staticメソッド)

最も良く使われる方法
Java側のstaticなメソッドをコールする
(基本的にPluginは シングルトンで作る事が多い)

ネイティブ
package com.sample;
public class plugin{
  public static String func(int n){
    return( "Hello world!!" + Integer.toString(n) );
  }
}
UNITY
  using( AndroidJavaClass cls = new   AndroidJavaClass("com.sample.plugin")))
  {
    string str = cls.CallStatic<string>("func",1);
  }

ネイティブ側は説明不要。
UNITY側は、AndroidJavaClassに クラス名をフルネームで与え、classを取得
取得したclassのstaticメソッドを呼ぶのがCallStatic
ジェネリクスには 戻り値の型を指定し、第一引数は関数名。第二引数以降に引数を指定する

引数や戻り値に使えるのは、プリミティブ型とstring型で、それ以外は AndroidJavaObject型で受け取る

Javaでバインド(staticプロパティー)

プロパティーの場合も ほぼ同じ

ネイティブ
package com.sample;
public class plugin{
  public static String mStr = "aaaaa";
}
UNITY
  using( AndroidJavaClass cls = new AndroidJavaClass("com.sample.plugin")))
  {
    string str = cls.GetStatic<string>("mStr");
    cls.SetStatic("Hello World");
  }

GetStatic<> と、SetStatic でオケー

Javaでバインド(non staticメソッド)

non staticな場合は、インスタンス作成が必要なので AndroidJavaObjectを使う
(AndroidJavaClass はインスタンスを作らないのでStaticフィールドにアクセスする事しかできない)

ネイティブ
package com.sample;
public class plugin{
  String mStr;
  plugin(String str){
    mStr = str;
  }
  public String func(int n){
    return( mStr + Integer.toString(n) );
  }

}
UNITY
  using( AndroidJavaObject obj = new AndroidJavaObject("com.sample.plugin","Hello World!") )
  {
    string str = obj.Call<string>("func", 2);
  }

AndroidJavaObjectの最初の引数はパッケージ名だが、その後からはコンストラクタの引数だ
AndroidJavaObjectで プラグインのclassのインスタンスを作成し、non staticメンバーを Call
もちろん、プロパティーには Get、Set 関数が容易されている
あまり UNITY側でプラグインクラスをインスタンス化する事はしないかもしれないが
例えば プラグインを Singletonで実装し、non staticメンバにアクセスする事は 時々やるかな。

UNITY
  using( AndroidJavaClass cls = new AndroidJavaClass("com.sample.plugin"))
  {
    using( AndroidJavaObject obj = cls.GetStatic<AndroidJavaObject>("getInstance") )
    {
      string str = obj.Call<string>("func", 2);
    }
  }

getInstance()で プラグインのインスタンスを取得し、AndroidJavaObject型で受け、non staticアクセスをしている

C#で完結させる

ちょっとした処理にわざわざJar作るのも面倒なので
可読性が失われない小さいプラグインは、直接書いてしまった方が楽

例えば、アプリケーションのBundleバージョンの取得

UNITY
public getVersionName()
{
  AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
  AndroidJavaObject context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity").Call<AndroidJavaObject>("getApplicationContext");
  AndroidJavaObject pManager = context.Call<AndroidJavaObject>("getPackageManager");
  AndroidJavaObject pInfo = pManager.Call<AndroidJavaObject>( "getPackageInfo", context.Call<string>("getPackageName"), pManager.GetStatic<int>("GET_ACTIVITIES") );

  string versionName = pInfo.Get<string>( "versionName" );
  return versionName;
}

Staticとnon static を分けて考えなければならないのが、少し面倒だけど
Javaとの連携は比較的簡単Death!!

93
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
YukiMiyatake
C++が喋れる ゲームプログラマ インフラ、サーバ、UNITY、ゲームエンジンが最近多いな・・ MONA: MPpuEnmqDYBCxSZyG5cBDt6UWtXczmRmkn BTC: 13JpgsF3n6K2WhjEeUuUUqS7V71gWdFx56 BCH: 18q6rfi9ynyTgynrB8tJ2eSDLPQM32RZk5
murasame
ゲーム、エンタメ、サーバインフラ等 少人数で技術力の高い仕事をする会社

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
93
Help us understand the problem. What is going on with this article?