West Hill 開発メモ

タグ:Asset

GIFファイルをランタイムでデコードして
連続したテクスチャを出力するスクリプトアセットを作りました。

UniGif - https://github.com/WestHillApps/UniGif
a10
アニメーション、透過、インターレース等のGIF87a、GIF89aフォーマットに対応しています。

WWWやStreamingAssetsから取ってきたGIFファイルを、  
以下のようにテクスチャリストとして取得できます。
 
int loopCount, width, height;
List<UniGif.GifTexture> gifTexList = UniGif.GetTextureList (www.bytes, out loopCount, out width, out height);
UniGif.GifTextureは1コマ分のTexture2dと次のテクスチャまでのディレイ時間を持っています。

詳しくはサンプルシーン(Assets/UniGif/Example/UniGifExample.unity)と  
サンプルコンポーネント(Assets/UniGif/Example/Script/UniGifTexture.cs)を参照。  

Unity4.3.4でPC(Mac, Win)、Android、iOSで確認していますが
多分他のバージョンやプラットフォームでも動きます。

Texture2D.SetPixelsでテクスチャを作成しているため、サイズの大きい画像だと展開にはそれなりの時間がかかります。


参考 
Unity Forum - animated gif is not working
http://forum.unity3d.com/threads/animated-gif-is-not-working.27873/

とほほのWWW入門 GIFフォーマットの詳細
http://www.tohoho-web.com/wwwgif.htm

時雨エノキオプト GIFデコーダサンプルプログラム解説 ver1.11
http://www.geocities.jp/warotarock/asen2ndgif001.html

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

Unity Asset Storeにて、2D弾幕が簡単に作れるアセット「Uni Bullet Hell」をリリースしました。



コンポーネントを追加してインスペクタ上でパラメタをいじるだけで好きな弾幕が撃てます。
シューティングゲームやシューティング以外のゲームでも、
弾幕出したいなって時に使えると思いますので、よろしくお願いします。

弾幕パターン例 >> WebPlayerサンプル
チュートリアル&リファレンス >> Uni Bullet Hellサポート
ss_01
※当アセットに使用している画像やサウンドは、
Unity Japanチュートリアルのものを使用させてもらっています。 
>> 2D Shooting Game Tutorial (Unity Japan)

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

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

westhillapp01://urlschemetest」のような独自のURLを使って、
Unity Androidアプリを起動する方法の実装メモです。

ブラウザや他のアプリからUnity Androidアプリを起動
custom_url_scheme_04
iOS版はこちら

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

実装手段として、Androidのプラグインを作成してプロジェクトに組み込みます。
Unityが使用しているUnityPlayerActivityを継承する方法もあるのですが、
同時に使用しているプラグイン等との衝突を避けるために、
独自のActivityを作成して、カスタムURLスキームからの起動時には
独自のActivityを立ちあげる→UnityPlayerActivityへ遷移という実装にしました。

参考:Building Plugins for Android
   (「Extending the UnityPlayerActivity Java Code」以下)

①まずは、独自のActivityを含むjarライブラリを作成します。
eclipseで新規Androidプロジェクトを作って、
右クリック→Properties→AndroidでIsLibraryにチェック。
custom_url_scheme_02
②Unity Adnroidで使用しているクラスを参照するため、
以下パス内にある classes.jar ファイルを「libs」フォルダ内に配置します。
Winの場合:Unityのインストールパス\Editor\Data\PlaybackEngines\androidplayer\bin
Macの場合:Unityのインストールパス/Unity.app/Contents/PlaybackEngines/AndroidPlayer/bin


③独自URL経由で起動するActivityを作成します。
IntentReceiveActivity.java
public class IntentReceiveActivity extends Activity {

	/* アクティビティ保持用 */
	private static Activity mThisActivity;

	/* アクティビティ遷移ハンドラ */
	private static Handler mMoveActivityHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// UnityPlayerProxyActivityへ遷移
			if (mThisActivity != null) {
				Intent i = new Intent(mThisActivity.getApplication(), UnityPlayerProxyActivity.class);
				mThisActivity.startActivity(i);
				mThisActivity.finish();
				mThisActivity = null;
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Context context = getApplicationContext();
		
		// SharedPreferences取得。UnityのPlayerPrefsでは、
		// バンドル名のSharedPreferencesを使用しているので合わせる
		SharedPreferences packagePrefs = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = packagePrefs.edit();
		
		// 指定のスキーム経由で起動されたフラグをSharedPreferencesに保存
		editor.putInt(getIntent().getData().getScheme(), 1);
		editor.commit();

		// アクティビティを保持
		mThisActivity = this;

		// アクティビティ遷移
		mMoveActivityHandler.sendEmptyMessageDelayed(0, 10);
	}

	@Override
	public void onBackPressed() {
		// バックキーで何もしない
		// super.onBackPressed();
	}
}
ここでは起動時のURLスキーム名をキーにしてSharedPreferencesにintのフラグを保存し、
Unityで使用している開始時のアクティビティUnityPlayerProxyActivityへ遷移するようにしています。

④↑で作成したAndroidプロジェクトをビルドして、「bin/」配下の プロジェクト名.jarファイル 
Unityプロジェクトビューのルート(フォルダ構成で言うとAssets直下)に「Plugins/Android」フォルダを作成して配置します。


⑤「Plugins/Android」フォルダに、 AndroidManifest.xml を作成します。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    android:installLocation="preferExternal"
    android:versionCode="1"
    android:versionName="1.0">
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"/>

    <application
        android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        android:debuggable="true">
        
        <activity android:name="com.unity3d.player.UnityPlayerProxyActivity"
                  android:label="@string/app_name"
                  android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:label="@string/app_name"
                  android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
        </activity>
        <activity android:name="com.unity3d.player.UnityPlayerNativeActivity"
                  android:label="@string/app_name"
                  android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
            <meta-data android:name="android.app.lib_name" android:value="unity" />
            <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
        </activity>
         
        <!-- カスタムURLスキームからの起動用Activity -->
        <activity android:name="【ライブラリのパッケージ名】.IntentReceiveActivity">
            <intent-filter>
                <data android:scheme="【URLスキーム名】" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <action android:name="android.intent.action.VIEW" />
            </intent-filter>
        </activity>
         
    </application>
</manifest>
大事なのは<!-- カスタムURLスキームからの起動用Activity -->のIntentReceiveActivity定義部分です。
カスタムURLスキームリンク要求時に、指定のActivityでアプリを立ち上げる設定をしています。

【ライブラリのパッケージ名】の部分に①で作成したライブラリのパッケージ名を入れ、
【URLスキーム名】の部分を使用したい独自スキーム名にします。
※スキーム名は、URLの":"以前の部分になります。↑の例でいうと westhillapp01

※同時に使用しているプラグイン等でAndroidManifestが既に作られている場合には、
<!-- カスタムURLスキームからの起動用Activity -->部分のみ追記すれば問題ないです。


⑥Unity側で、カスタムURLスキームからの起動か否かを
以下のようにPlayerPrefsを使用して②で保存したフラグから判別することが出来ます。
bool launchFromCustomUrlScheme = PlayerPrefs.GetInt("【URLスキーム名】", 0) == 1 ? true: false;
PlayerPrefs.DeleteKey("【URLスキーム名】"); 

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

Unityでのパフォーマンス低下の原因の一つであるDrawCallを減らすためのAsset、
Draw Call Minimizerを使用した際の問題点とその対策方法のまとめです。

Draw Call Minimizer (free)

実装時のバージョンはUnity4.0.0、Draw Call Minimizerのバージョンは1.3.6.2です。

基本的な使い方についてはテラシュールウェアさんの記事が参考になります。

[Unity3D]Draw Call Minimizerの使い方と問題について
http://terasur.blog.fc2.com/blog-entry-215.html


以下が自分の環境で使用した際に起きた問題点とその対策方法です。

●まとめたオブジェクトが実行時に真っ黒になってしまう
 オブジェクトのマテリアルで使用しているテクスチャが大きすぎると、
 1枚に結合できずに黒くなってしまうので、
 テクスチャのインポート設定でMax Sizeを小さいサイズに変更する。 

●エラーメッセージUnsupported texture format needs to be ARGB32, RGBA32, BGRA32, RGB24, Alpha8 or DXTが出る
 メッセージの通り、テクスチャのインポート設定でAdvancedにして、
 FormatをARGB32、RGBA32、RGB24、Alpha8、DXTのいずれかに変更する。

●エラーメッセージCannot combine textures when using Unity's default material textureが出る
 これもメッセージの通り、デフォルトテクスチャは使用できないので、
 何でもいいのでテクスチャを張り付ける。

●一部のモデルでout of boundsエラーが出る
 エラーが発生しているスクリプトの該当箇所をコメントアウトする。
 対応箇所は「MeshCombineUtillity」の以下部分。

 mesh.colors = colors.ToArray();
 mesh.uv1 = uv1.ToArray();
 mesh.uv2 = uv2.ToArray();

●オブジェクトの当たり判定がなくなり、すり抜けてしまう
 実行時にColliderが外れてしまうので 、「OptimizedCombinedChildren」の
 150行目付近のメッシュを結合しているfor文の中にMeshColliderを付ける処理を追加する。

 go.AddComponent ("MeshCollider");
 go.GetComponent<MeshCollider>().sharedMesh = combinedMeshes[i];


ちなみに、Draw Call MinimizerはOptimizedCombineChildren配下の全オブジェクトを1つにしてくれるのではなく、共通のシェーダを使用しているオブジェクトが1つにまとめられます。
(2種類のシェーダを使っていたら2つのオブジェクトにまとめられます。)

マテリアルを結合しているので当たり前なのですが、複数のシェーダを使用している場合には注意が必要です。

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

このページのトップヘ