チラ裏。本当のメモです。あしからず
UnityでAndroidを開発している時の試行錯誤の末路。
AndroidのMainActivityを生成するときのテンプレート(UnityPlayerNativeActivity)をカスタマイズし、
UnityのC#からAndroid標準のファイルChoserを呼び出してファイルパスを取得できるようにやったときのめも。うまくいっている気はする。
呼び出され側
<Unity_home>\Editor\Data\PlaybackEngines\androidplayer\com\unity3d\player のUnityPlayerNatieActivity.javaを編集
package com.unity3d.player; import android.app.NativeActivity; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.net.Uri; import android.content.Intent; public class UnityPlayerNativeActivity extends NativeActivity { private static final int REQUEST_GALLERY = 0; private boolean isRoad = false; private String filepath = null; protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code // Setup activity layout @Override protected void onCreate (Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); getWindow().takeSurface(null); setTheme(android.R.style.Theme_NoTitleBar_Fullscreen); getWindow().setFormat(PixelFormat.RGB_565); mUnityPlayer = new UnityPlayer(this); if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true)) getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(mUnityPlayer); mUnityPlayer.requestFocus(); } // Quit Unity @Override protected void onDestroy () { mUnityPlayer.quit(); super.onDestroy(); } // Pause Unity @Override protected void onPause() { super.onPause(); mUnityPlayer.pause(); } // Resume Unity @Override protected void onResume() { super.onResume(); mUnityPlayer.resume(); } // This ensures the layout will be correct. @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mUnityPlayer.configurationChanged(newConfig); } // Notify Unity of the focus change. @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mUnityPlayer.windowFocusChanged(hasFocus); } // For some reason the multiple keyevent type is not supported by the ndk. // Force event injection by overriding dispatchKeyEvent(). @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_MULTIPLE) return mUnityPlayer.injectEvent(event); return super.dispatchKeyEvent(event); } // Pass any events not handled by (unfocused) views straight to UnityPlayer @Override public boolean onKeyUp(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } /*API12*/ public boolean onGenericMotionEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } // Extend public void pickPhoto() { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, REQUEST_GALLERY); isRoad = true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub if(requestCode == REQUEST_GALLERY && resultCode == RESULT_OK) { try { String[] columns = { MediaColumns.DATA }; Cursor cursor = getContentResolver().query(data.getData(), columns, null, null, null); if (cursor.moveToFirst()) { File file = new File(cursor.getString(0)); filepath = file.getAbsolutePath(); } } catch (Exception e) { filepath = null; } finally { isRoad = false; } } } public boolean isRoading() { return isRoad; } public String getPath() { return filepath; } }
呼び出す側
using UnityEngine; using System.Collections; public class PickPhoto : MonoBehaviour { private static string activity = "com.unity3d.player.UnityPlayer"; enum PpState {PICKSTART, PICKING, DEFAULT}; private PpState state = PpState.DEFAULT; private AndroidJavaClass cUnityPlayer; private AndroidJavaObject oCurrentActivity; // Use this for initialization void Start () { // Find the UnityPlayer and get the static current activity cUnityPlayer = new AndroidJavaClass (activity); oCurrentActivity = cUnityPlayer.GetStatic<AndroidJavaObject> ("currentActivity"); } // Update is called once per frame void Update () { switch (state) { case PpState.PICKING: if(!IsRoading()) { state = PpState.DEFAULT; SetImage(GetPath()); } break; case PpState.PICKSTART: PickStart(); state = PpState.PICKING; break; case PpState.DEFAULT: if (Input.GetMouseButtonDown(0)) { state = PpState.PICKSTART; } break; } } void PickStart() { oCurrentActivity.Call("pickPhoto"); } bool IsRoading() { return oCurrentActivity.Call<bool>("isRoading"); } string GetPath() { return oCurrentActivity.Call<string>("getPath"); } void SetImage(string filepath) { // Debug.Log("path:" + GetPath()); GameObject go = GameObject.Find("GameMaster"); go.GetComponent<GMSelectChara>().setImage(filepath); } }