うえすと開発メモ

NGUIを使用してスクロールリストの実装をする際にはDraggablePanelを使うことが多いと思いますが、設定によっては一部のAndroid端末で表示がおかしくなることがあります。

ドラゴンツイートではタイムラインの表示にDraggablePanelを使用していたので、
一部端末で以下のような表示になってしまいました。
※現象を確認できた端末はXperia acro HD(IS12S)、Xperia NX(SO-02D)等。

環境はUnity4.2.0、NGUIのバージョンは2.6.4です。
ngui_list_01 
DraggablePanel以下のAtlasテクスチャが真っ黒になってしまっています。 

原因はPanelのClippingの設定が「Alpha Clip」になっていたからでした。
ngui_list_03
赤枠のところの設定を「Soft Clip」にすることで、解消します。
Soft Clipだとスクロールの端の方がぼやけるのですが、Softnessのパラメタを1にすれば気にならなくなります。 
ngui_list_02 
無事表示されました。 

ちなみに「Hard Clip」は古いGPUドライバの端末でサポートされていないので推奨されていません。
http://d.hatena.ne.jp/shinriyo/20130501/p2

開発中の動作確認に使用していたGalaxyNexusでは「Alpha Clip」でも問題なかったので
レビューで指摘されるまで気づかなかったのですが、やはり色々な端末で検証する事は大事ですね。

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

Unityで作ったプロジェクトを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

このページのトップヘ