Help us understand the problem. What is going on with this article?

Unityからネィティブプラグインを使う

More than 3 years have passed since last update.

ネィティブ周りのど素人が苦戦しながら調べてみました。

検証環境:
Windows 7 32bit
Android Studio 2.1.3
Unity 5.3.5p8
JDK 1.8
実機Android 5.0.1
実機iOS 8.3
Xcode 7.2.1

プラグインを配置するフォルダを作成

キャプチャ.PNG
AndroidとiOSのフォルダをPluginsのしたに作成します。

Android用にjarファイルの作成

ざっと調べた限り手段(C++とか)がいくつかあるようですが、今回はJavaで連携することとします。

Android Studioでjarファイルを作成します。
「Start a new Android Studio project」
にて新規プロジェクトを作成します。

ちょっとわかりくいですが、今回は「Twitter」というUnityのプロジェクトの直下に「MyPlugins」というAndroid Studioのプロジェクトを作成します。
ちなみに別にここに作成することは必須ではないです。
都合上、Unityプロジェクトに含めてみただけです。自分がわかりやすいところに作成してください。
キャプチャ.PNG

「Add No Activity」でActiviyなしのシンプルなプロジェクトを作成します。
キャプfチャ.PNG

下図のような感じで新規Moduleを作成します。
キャプチャ.PNG

「Android Library」で作成します。
キャffプチャ.PNG

「twitter」という名前で作成しました。
キャ1プチャ.PNG

Unityの機能をAndroidから使うため、classes.jarを配置します。
今回の環境では以下に存在しました。
C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar

android.jarも配置します。
C:\Users\okuhiiro\AppData\Local\Android\sdk\platforms\android-23\android.jar

これを下記場所にコピーします。
キャプチャ.PNG

ソースコードを以下に記述しました。
トーストを出すだけの簡単なものです。
キャqプチャ.PNG

Twitter.java
package okuhiiro.twitter;

import android.app.Activity;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;

public class Twitter {
    public static void ShowToast() {
        final Activity activity = UnityPlayer.currentActivity;
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(activity, "OK!!", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

UnityPlayerがうまくimportできない場合は、下記ボタンでSyncしてください。
キャプチャ.PNG

作成したtwitterモジュールのbuild.gradleを編集します。
デフォルトのファイルから追加した行とコメントアウトしたところは下記になります。

build.gradle
//apply plugin: 'com.android.library'
apply plugin: 'java' // 追加

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

dependencies {
    //compile 'com.android.support:appcompat-v7:23.+'
    compile fileTree(dir: 'libs', include: ['*.jar'])
    //testCompile 'junit:junit:4.12'

    sourceCompatibility = 1.7 // 追加
    targetCompatibility = 1.7 // 追加
}

// 以下追加
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

以下コマンドでビルドします。
初回はどこからかビルドするためのものをダウンロードしてくる可能性があるので時間がかかりました。

C:\Users\okuhiiro\Unity\Twitter\MyPlugins>gradlew jar

警告: [options] ブートストラップ・クラスパスが-source 1.7と一緒に設定されていません
とでましたが今回は無視:laughing:

以下場所にjarファイルが生成されました。
キャプチャ.PNG

UnityからjarのメソッドをCallする

作成したjarを「プラグインを配置するフォルダを作成」で作成した「Android」の下にいれます。

適当にuGUIでボタンを作成しました。
キャプチャ.PNG

このボタンに下記イベントを割り当てています。

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

public class TwitterController : MonoBehaviour {

    public void OnTwitter()
    {
#if UNITY_EDITOR
        Debug.Log("UnityEditorでは使用できません");
#elif UNITY_ANDROID
        // パッケージ名 + クラス名を引数にする
        using (AndroidJavaClass javaClass = new AndroidJavaClass("okuhiiro.twitter.Twitter"))
        {
            // そのクラスのメソッドを指定する.
            // 引数があるの場合は、第2引数以降がそのメソッドの第1引数に該当する.
            javaClass.CallStatic("ShowToast");
        }
#endif
    }
}

ボタンを押下すると無事トーストがでました。
IMG_0081.PNG

iOS用にmmファイルの作成

続いてiOS。mmファイルをおくだけであとはUnityがやってくれるのでAndroidと違い比較的簡単。

下記の「プラグインを配置するフォルダを作成」で作成した「iOS」の下にいれます。

extern "C" {
    void TestAlert() {
        UIAlertView *alert = [[UIAlertView alloc]
                    initWithTitle:@"タイトル"
                    message:@"ほげ"
                    delegate:nil
                    cancelButtonTitle:@"OK" otherButtonTitles:@"NO", nil
        ];
        [alert show];
    }
}

Unityからobject-cのメソッドをCallする

Androidと同じで適当にuGUIでボタンを作成しイベントをつけておきます。
つけるイベントは下記です。上のAndroidのやつに追記しました。
UNITY_IOSで分岐されているところが追加したところです。

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

public class TwitterController : MonoBehaviour {
#if UNITY_IOS
    [DllImport("__Internal")]
    static extern void TestAlert();
#endif

    public void OnTwitter()
    {
#if UNITY_EDITOR
        Debug.Log("UnityEditorでは使用できません");
#elif UNITY_ANDROID
        // パッケージ名 + クラス名を引数にする
        using (AndroidJavaClass javaClass = new AndroidJavaClass("okuhiiro.twitter.Twitter"))
        {
            // そのクラスのメソッドを指定する.
            // 引数があるの場合は、第2引数以降がそのメソッドの第1引数に該当する.
            javaClass.CallStatic("ShowToast");
        }
#elif UNITY_IOS
        TestAlert();
#endif
    }
}

ボタンを押下すると無事アラートがでました。
IMG_0081.PNG

続き

次回で本当にやりたかったこと。

okuhiiro
ゲーム開発にかかわる記事が主です
gumi
Python、Erlang、Elixir などちょっと変わった技術でゲームをつくったりする会社。プログラマだけじゃなく、企画、デザイン、イラストなど開発全般揃ってます。
http://gu3.co.jp
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