MeshMergerの魔力
Untiyで作業しているとき、同一マテリアルのオブジェクトをまとめるのにMeshMergerが使えます。
これは、複数のメッシュを実行時に1つにまとめてくれるスクリプトで、
オブジェクトが大量にあってDrawCallsが凄いことになっている場合に使えます。
Unify - MeshMerger
http://www.unifycommunity.com/wiki/index.php?title=MeshMerger
いやー、劇的ですね!
一概にDrawCallsを減らせばいいというものでも無いと思いますが、これだけ減ると気持ちがいいです。
UnityでDatabase.comにOAuth2.0する
Salesforce.comのDatabase.comにOauth2.0でログインする方法。
①はハマりどころ。
セキュリティーキーは、Database.comメニューの
My Personal Information→Reset My Security Tokenでボタンをクリックするとメールで送られてくる。
②、③は
App Setup→Develop→Remote Accessでアプリを登録して取得
void OnGUI () { if (GUILayout.Button ("Login")) { StartCoroutine (DoLogin ()); } } private string OAUTH_ENDPOINT = "/services/oauth2/token"; private string REST_ENDPOINT = "/services/data"; IEnumerator DoLogin () { string url = "https://" + "na1.database.com" + OAUTH_ENDPOINT; WWWForm wf = new WWWForm (); string secKey = "<you api security key>"; string username = "<your login account for database.com>"; string password = "<your password for database.com>"; string client_id = "<your Consumer Key>"; string client_secret = "<your Consumer Secret>"; wf.AddField ("grant_type", "password"); wf.AddField ("username", username); wf.AddField ("password", password+secKey); //パスワード+API セキュリティーキー → ① wf.AddField ("client_id", client_id); //→② wf.AddField ("client_secret", client_secret); //→③ WWW www = new WWW (url, wf); /* //XMLで取得する場合 Hashtable h = new Hashtable (); h ["Accept"] = "application/xml"; WWW www = new WWW (url, wf.data, h); */ yield return www; Debug.Log (www.error); Debug.Log (www.text); //www.text にJSONでaccess_tokenなどが返ってくる }
簡単にクラウドでデータベース使うならDatabase.comはすごい便利なんじゃないかと推測中。
UnityでInput.GetButtonをエミュレートできるようにする
PlatformControllerなどをつかうと、Input.GetButton("Jump")みたいなのがいっぱい使われています。
で、GUIのボタンを押したらジャンプとかしようと思って、Input.SetButtonDownとかやりたいのですが、そんなものはありません。
ということで探していると、フォーラムにInputBrokerとか作ればいいんじゃね?っていうエントリがあったので作って見ました。
#pragma strict private static var buttons : ArrayList = new ArrayList(); private static var upButtons : ArrayList = new ArrayList(); private static var downButtons : ArrayList = new ArrayList(); private static var lastFrame:int =-1; private static function Clean () :void { if ( lastFrame >0 && Time.frameCount > lastFrame + 1) { upButtons.Clear (); downButtons.Clear (); lastFrame = -1; } } function Update(){ Clean(); } static function GetButton (s:String) : boolean { return buttons.Contains (s) || Input.GetButton (s); } static function GetButtonDown (s:String) : boolean { return downButtons.Contains (s) || Input.GetButtonDown (s); } static function GetButtonUp (s:String) : boolean { return upButtons.Contains (s) || Input.GetButtonUp (s); } static function SetButtonDown ( s:String ) : void { lastFrame = Time.frameCount; downButtons.Add (s); buttons.Add (s); } static function SetButtonUp ( s:String ) :void { lastFrame = Time.frameCount; buttons.Remove (s); upButtons.Add (s); }
このスクリプトをInputBroker.jsとかの名前で保存(Standard Assets配下に置くのがいいかな?)します。
で、シーンに空のオブジェクトを作ってそこにアタッチ。
あとは、Input.GetButtonやInput.GetButtonDownを、InputBroker.GetButton, InputBroker.GetButtonDownに置換すれば完成。
これで、任意のタイミングでInputBroker.SetButton("Jump")とかすると、ジャンプのボタンを押したことになります。
もっといい方法がある?のかな?
Unity3.4 + Androidでスクリーンキャプチャ
Untiy3.4 + Androidの環境では
Application.CaptureScreenshot("screenshot.png");
でスクリーンショットを取ると、
保存されたPNGファイルが壊れるという現象が起こります。
これは、既知のバグであり3.5 beta1では修正されているようですが、
急ぎで必要だったためJPGで保存する回避策を試してみました。
JPGへのエンコードにはUnityのフォーラムで提供されているJPGEncoderを使います。
http://forum.unity3d.com/threads/31737-Convert-PNG-to-JPG-without-writing-to-disk
これを使ってスクリーンショットを取るJPGScreenShot.csスクリプトを作成しました。
using UnityEngine; using System.Collections; using System.IO; public class JPGScreenShot : MonoBehaviour { // Use this for initialization void Start () { Debug.Log ("Taking JPGScreenShot"); StartCoroutine (ScreenShot ()); } IEnumerator ScreenShot () { // エンコーダに渡すテクスチャの作成 Texture2D tex = new Texture2D (Screen.width, Screen.height, TextureFormat.RGB24, false); // バッファをテクスチャに書きこむ tex.ReadPixels (new Rect (0, 0, Screen.width, Screen.height), 0, 0); tex.Apply (); // split the process up--ReadPixels() and the GetPixels() call inside of the encoder are both pretty heavy yield return new WaitForSeconds (0.1f); // エンコーダ作成 JPGEncoder encoder = new JPGEncoder (tex, 75.0f);// // エンコード開始 encoder.doEncoding(); // エンコード終了まで待機 while (!encoder.isDone) { yield return new WaitForSeconds (1f); } // ファイル書き出し Debug.Log ("Write to : " + Application.persistentDataPath + "/screenshot.jpg"); File.WriteAllBytes (Application.persistentDataPath + "/screenshot.jpg", encoder.GetBytes ()); } }
呼び出しは、こんな感じで。
//Javascriptから (new GameObject()).AddComponent("JPGScreenShot");
//C#スクリプトから (new GameObject()).AddComponent(tyepof(JPGScreenShot));
きっとすぐに3.5が出るのであんまり使う機会はないかも。。。
取り敢えずメモ。
追記:
これを使うには、JPGEncoder.csが必要です。
ダウンロードはこちらから
http://bit.ly/jpgencoder
UnityからAndroidのインテントを呼び出す
UnityからAndroidのメソッド(なんかおかしな言い方だが気にしない、、、)を呼び出すには、
AndroidJavaObject#Callが使えるのですが、
戻り値がプリミティブじゃない場合の呼び出し方で悩んだので記録しておきます。
Unity - Scripting API: AndroidJavaObject.Call
戻り値無しなら
AndroidJavaObject#Call("method name", args[]);
戻り値int型ならジェネリクスを使って
AndroidJavaObject#Call<int>("method name", args[]);
と言う感じで、ドキュメントにあります。
で、戻り値がプリミティブじゃないときは書いてなかったので、試行錯誤しました。
AndroidJavaObject.Call<AndroidJavaObject>("method name", args[]);
と言うふうに、AndroidJavaObjectを指定してやればいいようです。
解れば当然なのですが、、、
ということで、UnityからAndroidのSENDインテントを呼び出してみるコードはこんな感じ。
// Find the UnityPlayer and get the static current activity AndroidJavaClass cUnityPlayer = new AndroidJavaClass ("com.unity3d.player.UnityPlayer"); AndroidJavaObject oCurrentActivity = cUnityPlayer.GetStatic<AndroidJavaObject> ("currentActivity"); // Get defenitions of Intent and it's constructor. AndroidJavaObject oIntent = new AndroidJavaObject ("android.content.Intent"); // Call some methods oIntent.Call<AndroidJavaObject> ("setAction", "android.intent.action.SEND"); oIntent.Call<AndroidJavaObject> ("setType", "text/plain"); oIntent.Call<AndroidJavaObject> ("putExtra", "android.intent.extra.TITLE", "Hello"); // Start the activity! oCurrentActivity.Call ("startActivity", oIntent); //Dispose them. Not sure if I need to do it or not... oIntent.Dispose (); oCurrentActivity.Dispose ();
Unityだけで完結できて、結構短いコードでもいけるので良い感じ。
UnityマスターブックARをリリースしました
Unityマスターブックの表紙で遊べるARゲームを作って見ました。
https://market.android.com/details?id=jp.ac.sojou.cis.izumi.unity.masterbook.ar&feature=search_result
本の表紙を認識して、クロックが出現します。
ARライブラリはQCARを使っています。
https://ar.qualcomm.at/qdevnet/
ARがこんなに手軽に使える時代になってしまったとは、、、