V系バンドマンがゲームを開発するんご

V系バンドマンの僕がゲームを開発してみるんご

【Unity】【iOS】ステータスバーの背景色を設定する

Unity、iOSでステータスバーを表示した時に、背景が透明なので黒くしたい。

https://www.facebook.com/groups/unityuserj/permalink/1152148234845115

色々調査しました・・・

やった方法
Assets/Plugins/iOS

StatusBarBackgroundColor.mmを作成

extern UIViewController* UnityGetGLViewController();

extern "C" {
    void _Set();
}

void _Set() {
    // ステータスバーの背景色を設定(viewを追加)
    UIViewController* parent = UnityGetGLViewController();
    
    UIView *statusBar         = [[UIView alloc] initWithFrame:CGRectMake(0, 0, parent.view.window.frame.size.width, 20)];
    statusBar.backgroundColor = [UIColor blackColor];
    [parent.view addSubview:statusBar];
}

Assets/Plugins

StatusBarBackgroundColor.csを作成

using UnityEngine;
using System.Runtime.InteropServices;

public class StatusBarBackgroundColor { 
	[DllImport("__Internal")]
	private static extern void _Set();
	public static void Set() {
		_Set();
	}
}

最初のシーンのどっかのAwakeで
StatusBarBackgroundColor.Set();
を呼ぶ。

【Android】【Unity】ギャラリーから画像を持ってきたい その3

前回の続きです。

前回の記事はこちら
vprog.hatenablog.com

前回、取得した画像パスをUnity側で取得してみましょ。
java側からunity側に送るには
UnityPlayer.UnitySendMessage
を、java側に記述すればいいそうです。

しかし、全部c#でできないのかな?って思って色々試してみました。

AndroidJavaProxyを使用します。

参考サイト
qiita.com

AndroidStudio
GalleryListener.javaを作成

public interface GalleryListener {
    public void onRestart();

    public void onStart();

    public void onResume();

    public void onPause();

    public void onStop();

    public void onActivityResult(int requestCode, int resultCode, Intent data);
}

AndroidStudio
GalleryActivity.java

    private static GalleryListener my_listener;
    public static void SetListener(GalleryListener listener)
    {
        my_listener = listener;
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult: " + requestCode + " : " + resultCode);
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode != RESULT_OK)
        {
            setResult(resultCode);
            finish();
            return;
        }
        if(my_listener != null) {
            my_listener.onActivityResult(requestCode, resultCode, data);
        }
        setResult(resultCode);
        finish();
    }

Unity
ActivityListener.cs

public class ActivityListener : AndroidJavaProxy
{
	public Action<int,int,AndroidJavaObject> onActivityResultEvent;

	public ActivityListener()
		: base("com.sample.samplegame.lib.GalleryListener")
	{
	}

	public void onRestart()
	{
	}

	public void onStart()
	{
	}

	public void onResume()
	{
	}

	public void onPause()
	{
	}

	public void onStop()
	{
	}

	public void onActivityResult(int requestCode, int resultCode, AndroidJavaObject data)
	{
		Debug.Log(requestCode + " : " + resultCode + " : " + data);

		onActivityResultEvent(requestCode, resultCode, data);
	}
}

Sample.cs

	private ActivityListener m_Listener;

	void Start () {
		using (AndroidJavaClass javaCalss = new AndroidJavaClass ("com.sample.samplegame.lib.GalleryActivity")) {
			javaCalss.CallStatic ("SetListener", m_Listener = new ActivityListener() );
		}
        }
	void OnGUI(){
		if(GUILayout.Button("gallery", GUILayout.Width(300), GUILayout.Height(200))){
			using (AndroidJavaClass javaCalss = new AndroidJavaClass ("com.sample.samplegame.lib.GalleryActivity")) {
				javaCalss.CallStatic ("OpenGallery" );
			}
		}
	}

実機で実行して、画像を選択するとUnityのログ側で出力されます。

では、画像パスもc#で取得してみましょう。

Unity
Sample.cs

	void Start () {
		using (AndroidJavaClass javaCalss = new AndroidJavaClass ("com.sample.samplegame.lib.GalleryActivity")) {
			javaCalss.CallStatic ("SetListener", m_Listener = new ActivityListener() );
		}

		m_Listener .onActivityResultEvent = (int requestCode, int resultCode, AndroidJavaObject data) => {
			var d = data.Call<AndroidJavaObject>("getData");
			using( AndroidJavaClass dd = new AndroidJavaClass("android.provider.DocumentsContract") ){
				var strDocId = dd.CallStatic<string>("getDocumentId", d);
				var strSplittedDocId = strDocId.Split(":"[0]);
				var strId = strSplittedDocId[strSplittedDocId.Length - 1];
				using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
					using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) {
						var r = activity.Call<AndroidJavaObject>("getContentResolver");
						var c = r.Call<AndroidJavaObject>("query",
							new AndroidJavaClass("android.provider.MediaStore$Images$Media").GetStatic<AndroidJavaObject>("EXTERNAL_CONTENT_URI"),
							new string[]{
								new AndroidJavaClass("android.provider.MediaStore$MediaColumns").GetStatic<string>("DATA")
							},
							"_id=?",
							new string[]{strId},
							null
						);
						if(c.Call<bool>("moveToFirst")){
							m_ImagePath = c.Call<string>("getString",0);
							Debug.Log(m_ImagePath);
						}
						c.Call("close");
					}
				}
			}
                }
        }

これで画像パスがログに表示されました。

answers.unity3d.com

さて、パスを取得したのでパスからテクスチャを作成してみましょう。

Unity
Sample.cs

			var imageByte = System.IO.File.ReadAllBytes(m_ImagePath);
			var texture = new Texture2D(0,0);
			texture.LoadImage(imageByte);
			m_Picture.sprite = Sprite.Create( texture, new Rect(0f, 0f, t.width, t.height), Vector2.zero);

これで、テクスチャを作成して表示ができるようになったと思います。

【Android】【Unity】ギャラリーから画像を持ってきたい その2

さて前回の続きです。

前回はこちら。

vprog.hatenablog.com

今回は、開いたギャラリーから画像のパスを習得してみましょう。

マニュフェストファイルにパーミッションを追加します。

AndroidStudio
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sample.samplegame.lib">

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true">
        <activity android:name=".GalleryActivity">
            <intent-filter>
                <action android:name="androidnativeactions.Gallery" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
</manifest>

AndroidStudio
GalleryActivity.java

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult: " + requestCode + " : " + resultCode);
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode != RESULT_OK)
        {
            setResult(resultCode);
            finish();
            return;
        }
        switch (requestCode)
        {
            case REQUEST_GALLERY_JELLYBEAN_BELOW:
                // 選択した画像のパスを取得する.
                String[] strColumns = {MediaStore.Images.Media.DATA };
                Cursor crsCursor = getContentResolver().query(data.getData(), strColumns, null, null, null);
                if(crsCursor.moveToFirst())
                {
                    Log.d(" PluginConnector", "REQUEST_GALLERY_JELLYBEAN_BELOW : " + crsCursor.getString(0));
                }
                crsCursor.close();
                break;

            case REQUEST_GALLERY_KITKAT_ABOVE:
                this.GetSelectedItemPath(data);
                break;
        }
        setResult(resultCode);
        finish();
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    private void GetSelectedItemPath(Intent data)
    {
        // 選択した画像のパスを取得する.
        String strDocId = DocumentsContract.getDocumentId(data.getData());
        String[] strSplittedDocId = strDocId.split(":");
        String strId = strSplittedDocId[strSplittedDocId.length - 1];

        Cursor crsCursor = getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                , new String[]{MediaStore.MediaColumns.DATA}
                , "_id=?"
                , new String[]{strId}
                , null);

        if (crsCursor.moveToFirst()) {
            Log.d("PluginConnector", "REQUEST_GALLERY_KITKAT_ABOVE : " + crsCursor.getString(0));
        }
        crsCursor.close();
    }

参考サイト
mslgt.hatenablog.com

実機で確認するとログに選択したパスが表示されました。

今回はここまでです。

【Android】【Unity】ギャラリーから画像を持ってきたい その1

やりたいこと

Android端末のギャラリーから画像を取得して表示したい

開発環境はMAC
Unity5.3.4f1
AndroidStudio2.2

色々、調べて参考にしたサイト

mslgt.hatenablog.com

まずはAndroidStudioでプラグインを作成します。

参考サイト

starzero.hatenablog.com

mizutanikirin.net


上記サイトを参考にプラグインを作成しました。

Gradleで作成したaarをコピーする記述ですが、自分のAndroidStudio2.2環境では動かなかったので修正。

task exportAar(type: Copy, dependsOn: assembleRelease)  {
    from('build/outputs/aar/')
    into('../../../Assets/Plugins/Android/')
    include('lib-release.aar')
    rename('lib-release.aar', 'samplegame-lib.aar')
}

これをこれに修正

task exportAar(type: Copy)  {
    dependsOn 'assembleRelease'
    from('build/outputs/aar/')
    into('../../../Assets/Plugins/Android/')
    include('lib-release.aar')
    rename(project.name + '-release.aar', project.name + '-lib.aar')
}

ビルドするとき、この、exportAarを実行すればUnityのPlugins/Androidにコピーされます。

では、参考サイト様のコードをそのまま引用して確認します。

Toastを表示するサンプル

AndroidStudio
NativePlugin.java

package com.sample.samplegame.lib;

import android.app.Activity;
import android.widget.Toast;

import com.unity3d.player.UnityPlayer;

public class NativePlugin {
    public static void showToast(final String message) {
        final Activity activity = UnityPlayer.currentActivity;
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(activity, message, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Unity
Sample.cs

using UnityEngine;

public class Sample : MonoBehaviour
{
    public void OnGUI ()
    {
        if(GUILayout.Button("Open")){
            using (AndroidJavaClass javaCalss = new AndroidJavaClass ("com.sample.samplegame.lib.NativePlugin")) {
                javaCalss.CallStatic ("showToast", "Test");
            } 
        }
    }
}

Androidの実機を繋げて確認
GUIボタンを押すとToastが表示されました。

では本題です。
まずはギャラリーを表示できるように試してみます。

AndroidStudioで新規作成でActivityを作成します。
後でAndoridManifest.xmlが必要になるため・・・

AndroidStudio
GalleryActivity.java

package com.sample.samplegame.lib;

import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

import static android.content.ContentValues.TAG;

public class GalleryActivity extends Activity {
    private static final int SDKVER_KITKAT = 19;
    private static final int REQUEST_GALLERY_KITKAT_ABOVE = 0;
    private static final int REQUEST_GALLERY_JELLYBEAN_BELOW = 1;

    public static void OpenGallery() {
        final Activity activity = UnityPlayer.currentActivity;
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent();
                intent.setType("image/*");
                if (Build.VERSION.SDK_INT < SDKVER_KITKAT) {
                    intent.setAction(Intent.ACTION_GET_CONTENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    activity.startActivityForResult(intent, REQUEST_GALLERY_JELLYBEAN_BELOW);
                } else {
                    intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    activity.startActivityForResult(intent, REQUEST_GALLERY_KITKAT_ABOVE);
                }
            }
        });
    }
}

Unity

Sample.cs

下記のように変更

public class Sample : MonoBehaviour
{
    public void OnGUI ()
    {
        if(GUILayout.Button("Open")){
            using (AndroidJavaClass javaCalss = new AndroidJavaClass ("com.sample.samplegame.lib.NativePlugin")) {
                javaCalss.CallStatic ("OpenGallery");
            } 
        }
    }
}

実機でギャラリーが表示されたのを確認。

次は、ギャラリーで選択した画像のパスを取得してみる。

startActivityForResultで起動すると結果が
onActivityResultに返ってくるということなので

AndroidStudio
GalleryActivity.java

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult: " + requestCode + " : " + resultCode);
    super.onActivityResult(requestCode, resultCode, data);
}

を追加しました。

実機で確認しましたが、ログが表示されません・・・

mslgt.hatenablog.com

こちらの参考サイトでも、onActivityResultが呼ばれなかったらしい。

UnityPlayerActivity.javaをマージしなくてはいけない・・・?

色々他に方法はないのか調べてみました。

answers.unity3d.com

やっとのおもいでたどり着いたのはここでした。

自分がやった対応は以下のようなものです。

AndroidStudio
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sample.samplegame.lib">

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true">
        <activity android:name=".GalleryActivity">
            <intent-filter>
                <action android:name="androidnativeactions.Gallery" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>

マニュフェストファイルをこのように変更。

AndroidStudio
GalleryActivity.java

public static void OpenGallery() {
    Intent intent = new Intent();
    intent.setAction("androidnativeactions.Gallery");
    UnityPlayer.currentActivity.startActivityForResult(intent, 999);//999は適当?
}
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent();
        intent.setType("image/*");
        if (Build.VERSION.SDK_INT < SDKVER_KITKAT) {
            intent.setAction(Intent.ACTION_GET_CONTENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            startActivityForResult(intent, REQUEST_GALLERY_JELLYBEAN_BELOW);
        } else {
            intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            startActivityForResult(intent, REQUEST_GALLERY_KITKAT_ABOVE);
        }
    }
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult: " + requestCode + " : " + resultCode);
        super.onActivityResult(requestCode, resultCode, data);
        setResult(resultCode);//追加
        finish();//追加
    }

これを実機でおこなうと
onActivityResultのログが表示されました。

長い道のりです・・・

書を収集する

FFRKコラボがもうすぐ終わるのでマルチでデシと戦って書を集めています。

FFRKコラボで☆5になるやつで持っているのは

光の4戦士

・ヴァン

・ティナ

の3つです。

 

光の4戦士とヴァンはアビ10までの書を集めたので、ティナを集め中です。

27日からはノート1つか、インク1つで書が交換できるようなので、セシルでも貰ってみようかな