2015年7月4日土曜日

AndroidWearとUnityを連携する 後編

こんにちは。野田です。

前回に引き続き、AndroidWearとUnityを連携させる方法を紹介します。

最終的な目的としてはCardboardアプリをAndroidWearで操作できるようにすることです。
ここで紹介するのは連携するところまでで、続きは7/18(土)のAndroidWearハッカソンでやろうと思ってます。
皆さんにも体験してもらえるようにCardboardもいっぱい持っていくので、興味がある方は、ぜひ参加してくださいね!
http://goo.gl/forms/hEq7Pch3fy

今回の後編では、Unity側の実装の説明をします。




■環境

  • Windows8.1
  • AndroidStudio1.3
  • Unity5.1.0f3


■Unity側の実装
1.概要
2.プロジェクト作成
3.jarファイルの配置
4.Scriptの追加
5.ビルド
参考サイト


1.概要
AndroidWearでタッチする毎に、カウントアップしていき、その値を画面に表示するアプリを作成していきます。
ソースは下記にあげています。
https://github.com/scarviz/TouchCounter


2.プロジェクト作成
3Dの新規プロジェクトを作成します。

GameObject > Create Empty
で、「GameObject」という名前の空のGameObjectを追加します。
Androidのメソッドを呼び出すScriptを関連付けるために使用します。

GameObject > 3D Object > 3D Text
で、3D Textを追加します。カウンタ表示に使用します。



3.jarファイルの配置
Assets > Plugins > Android
という構成になるようにフォルダを作成します。
作成したAndroidフォルダにAndroidPlugin.jarファイルを配置します。

ActivityやServiceなどのコンポーネントや、permissionを定義する場合は、AndroidManifestもAndroidフォルダに配置する必要があります。
今回はService、GooglePlayServicesを使用しているので、AndroidManifestが必要です。
AndroidManifestは下記にあるものをコピーしてください。
C:\Program Files\Unity\Editor\Data\PlaybackEngines\androidplayer

AndroidManifestにServiceを追加します。android:nameにはパッケージ名も記載する必要があります。
 
<service
    android:name="com.github.scarviz.touchu.TouchUService"
    android:enabled="true"
    android:exported="false">
</service>


また、GooglePlayServicesのmeta-dataも追加します。
android:valueは
android:value="@integer/google_play_services_version"
のままでは値がわからないため、下記のように直接値を設定します。バージョンに合わせて値を設定してください。
 
<meta-data
    android:name="com.google.android.gms.version"
    android:value="7571000" />


GooglePlayServicesを使用するには、ライブラリを含める必要があります。
(Android SDKのパス)\extras\google\google_play_services\libproject\google-play-services_lib\libs
の下にあるgoogle-play-services.jarを、同じくAndroidフォルダに配置します。



4.Scriptの追加
PluginsフォルダにScriptを追加します。今回はC#でTouchという名前にしました。
詳細は下記を参照してください。ここではAndroid側で作成したメソッドをどう呼び出すかを説明します。
https://github.com/scarviz/TouchCounter/blob/master/Assets/Plugins/Touch.cs



インスタンスを生成する必要がある場合は、「AndroidJavaObject」を、
staticなメンバにアクセスする場合は、「AndroidJavaClass」を使用します。

Touch.cs(69)
 
private void StartService() 
{
    try
    {
        using (AndroidJavaObject clsPlugin = new AndroidJavaObject(PLUGIN_CLASS_PATH))
        {
            // サービス起動
            clsPlugin.Call("startService", GAME_OBJ_NM);
        }
    }
    catch (Exception ex)
    {
        tetxMesh.text = ex.Message;
        Debug.LogError(ex.Message);
    }
}


ここでは、TouchServiceCtrlクラスのstartServiceメソッドを呼び出しています。
AndroidJavaObjectの引数に、TouchServiceCtrlクラスのパッケージ名+クラス名を指定します。
Callがメソッド呼び出しになります。第一引数がメソッド名、第二引数が可変パラメータになり、呼び出すメソッドの引数に合わせて設定します。
もし呼び出すメソッドに戻り値が必要な場合は、ジェネリクスを使ったCall<戻り値の型>というメソッドを使用すればOKです。
Android側のメソッド呼び出しは重い処理になるため、頻繁に呼ぶのは避けた方が良ようです。
また、すぐに解放するようにusingを使用する方が良いとのことです。

必要に応じて適宜処理するには、Callbackメソッドを使用すると良さそうですね。
下記のようなメソッドを用意します。

Touch.cs(50)
 
public void onCallBack(string mess)
{
    Debug.Log("Call CallbackMess");
    mCnt++;
    tetxMesh.text = mCnt.ToString();
}


Android側ではUnitySendMessageメソッドを使用してコールバックさせます。※詳細は前回参照。
 
UnityPlayer.UnitySendMessage(mGameObjName, CALLBACK_NM, ACTION_DOWN);

UnitySendMessageの第一引数のGameObject名は、コールバックメソッドを定義したScriptが紐づいているGameObjectの名前を指定します。第二引数はコールバックメソッド名、第三引数はコールバックメソッドの引数に渡す値になります。


5.ビルド
Androidでのビルド設定がまだの場合は、
File > Build Settings
で、Platformの一覧からAndroidを選択し、Switch Platformボタンを押下して、Androidに切り替えてください。

同じくBuild Settingsで、
Player Settings > Inspecter > Other Settings > Identification > Bundle Identifier
をAndroidWearと同じ(AndroidのServiceと同じ)パッケージ名にします。

Cardboardもそうですが、横画面固定の方が都合が良いと思います。
Inspecter > Resolution and Presentation > Orientation > Default Orientation
で、「Landscape Left」を選択します。

Build and Runボタンを押下し、ビルドとHandHeldへのインストールを実施します。
アプリが起動したら、AndroidWear側もアプリを起動し、Wearの画面をタッチしてみてください。
Unity画面でカウントアップされていますね。




これを使えば、AndroidWearからゲーム操作ができそうですね!



■参考サイト
Create An Android Plugin For Unity Using Android Studio
http://www.thegamecontriver.com/2015/04/android-plugin-unity-android-studio.html

プラグインから画像のパスを投げてMaterialにセットする
http://mslgt.hatenablog.com/entry/2015/05/05/004530

Androidネイティブ開発のすすめ
http://qiita.com/relzx/items/a35f7ab6dbacb48f7e26

やはりUNITYでAndroidプラグインを作るにはAndroidJavaClassが便利だ
http://qiita.com/YukiMiyatake/items/c8c2ef396fbf4457ba4f

Unity で Android ネイティブプラグインの実装 - 一定時間起動していない場合にローカル通知を出すバックグラウンド処理の実装
http://nirasan.hatenablog.com/entry/2014/06/24/142820

Using the Google Play Services library in an android plugin (Google Maps)
http://forum.unity3d.com/threads/using-the-google-play-services-library-in-an-android-plugin-google-maps.177574/

2 件のコメント:

  1. 去年の記事にコメントしてすみません。
    android wearで加速度センサの値を取得して、今回のようにunity画面で値を表示させることはできますか?
    android studioではうまくいくのですが、unityが絡むとよくわからなくなってしまいます。コードの書き方など詳しく教えていただけませんか?

    返信削除
    返信
    1. 完全に見落としてました…すいません。

      過去過ぎてほとんど覚えてないですが、この時のハッカソンで、
      wearの傾きをUnity側のモデルに反映させることをやったので、それが参考になると思います。
      下記がそのソースです。
      https://github.com/scarviz/Flight
      https://github.com/scarviz/FlightCtrl4Unity

      ただ、だいぶ前のやつなので、今ちゃんと動くか分からないです。

      削除