West Hill 開発メモ

UnityでiPhone、iPadとAndroid用のTwitterクライアントアプリ「ドラゴンツイート」を作りました。
Twitterやってる方は良かったら気分転換に使ってみてください。

DragonTweet - Retro RPG-style Twitter app for iPhone & Android. http://westhillapps.com/app/dragontweet.html
ss_01_ja
このアプリの制作に使用した主なAssetと用途はこんな感じです↓

・NGUI
https://www.assetstore.unity3d.com/#/content/2413
GUI全般。

・Prime31 Social Networking Combo
http://prime31.com/plugins#combos-social
iOS、Android両用のTwitter連携。
TwitterへログインしたりREST API叩いたりといった処理がラップされていて、
Unityスクリプトからの呼出を共通化できるので便利です。

このエントリーをはてなブックマークに追加 Clip to Evernote

Unityで作ったプロジェクトをiOSやAndroid向けにビルドする際に、
アイコンの下に表示されるアプリ名を言語別に変更(ローカライズ)する方法です。

↓のように英語の場合と日本語の場合で分けたいとき 
localize_01
iOSの場合は、Xcodeプロジェクトができた後に、InfoPlist.stringを追加する以下の方法で出来ます。
be-style [Unity] iOSアプリ名のローカライズ
http://blog.be-style.jpn.com/article/57050228.html 

Androidの場合は、Unityプロジェクトビューのルート(フォルダ構成で言うとAssets直下)に、「Plugins/Android/res」フォルダを作って、
その配下に日本語なら「values-ja」 フォルダを作ってstring.xmlファイルを配置します。

string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">日本語アプリ名</string>
</resources>

日本語アプリ名の箇所に好きな名前を入れる事で、端末の言語設定が日本語の場合に表示される名前を変えられます。

ちなみに、ローカライズファイルを用意していない言語の場合は、
Unityの「Edit→ProjectSettings→Player」内の「Product Name」に設定したデフォルト名が表示されます。 
localize_02

このエントリーをはてなブックマークに追加 Clip to Evernote

Unity Androidのアプリから、別アプリのインストール状況を調べる方法です。
アプリ間連携等の際に、アプリがインストールされていればアプリを開き、インストールされていなければストアへ飛ばす等の挙動をさせたいときに使用できます。

実装時のバージョンはUnity4.1.2。

対象のアプリがインストールされているかの判定には、
インストールされているアプリのパッケージ名をリストで取得して比較を行います。

今回はAndroidのJavaクラスやメソッドを呼び出すAndroidJavaObjectを使用して、
AndroidのPackageManagerから情報を取ってきます。

 参考:
Unity Script Reference AndroidJavaObject
AndroidDevelopers PackageManager

以下、指定パッケージのアプリがインストールされているか確認するCheckInstalledPackageメソッド

 CheckInstalledPackage
	/// 
	/// 指定パッケージのアプリがインストールされているか確認する
	/// 
	private bool CheckInstalledPackage( string packageName )
	{
		// 結果
		bool result = false;
		
		AndroidJNI.AttachCurrentThread();
		AndroidJNI.PushLocalFrame(0);
		try
		{
			// UnityPlayerActivityを取得
			using( AndroidJavaClass jcUnityPlayer = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ) )
			using( AndroidJavaObject joCurrentActivity = jcUnityPlayer.GetStatic<AndroidJavaObject>( "currentActivity" ) )			
			// PackageManagerを取得
			using( AndroidJavaObject joPackageManager = joCurrentActivity.Call<AndroidJavaObject>( "getPackageManager" ) )
			//インストールアプリ情報リストを取得
			using( AndroidJavaObject joApplicationInfoList = joPackageManager.Call<AndroidJavaObject>( "getInstalledApplications", 0 ) )
			{
				// リストの要素数取得
				int listSize = joApplicationInfoList.Call<int>( "size" );
				// 対象のパッケージ名があるか探す
				for( int i = 0; i < listSize; i++ )
				{
					// パッケージ名を取得			
					string pName = GetPackageName( joApplicationInfoList, i );
					// パッケージ名を比較
					if( !string.IsNullOrEmpty( pName ) && packageName.Equals( pName ) )
					{
						// インストールされている
						result = true;
						break;
					}
				}
			}
		}
		catch (System.Exception ex)
		{
			Debug.Log( ex.Message );
		}
		finally
		{
			AndroidJNI.PopLocalFrame(System.IntPtr.Zero);
		}
		
		return result;
	}
	
	/// 
	/// インストールアプリ情報リストから指定インデックスのパッケージ名を取得する
	/// 
	private string GetPackageName( AndroidJavaObject joApplicationInfoList, int index )
	{
		string pName = "";
		
		AndroidJNI.AttachCurrentThread();
		AndroidJNI.PushLocalFrame(0);
		try
		{
			// アプリ情報取得
			using ( AndroidJavaObject joApplicationInfo = joApplicationInfoList.Call<AndroidJavaObject>( "get", index ) )
			{
				// パッケージ名を取得
				pName = joApplicationInfo.Get<string>( "packageName" );
			}
		}
		catch (System.Exception ex)
		{
			return string.Empty;
		}
		finally
		{
			AndroidJNI.PopLocalFrame(System.IntPtr.Zero);
		}
		return pName;
	}

ネイティブ側からのプリミティブ型以外の戻り値(ActivityやPackageManagerやList等)はAndroidJavaObject型で受け取る事が可能です。

GetPackageNameを別メソッドに切り出しているのは、アプリが大量にインストールされている端末でのJNI ERRORを発生させないためです。
参考:[Fixed]: JNI local reference table summary (512 entries)

既存のアクティビティ内のメソッドを使うだけなら、Unity側の記述だけで使えるので便利です。

※Unity Android Player以外ではビルドが通らないので、メソッド全体を
#if UNITY_ANDROID
#endif

で括る。 また、エディタで実行するとエラーになるので、実機で確認しましょう。

このエントリーをはてなブックマークに追加 Clip to Evernote

このページのトップヘ