Unity × GPS × GoogleMapsAPI で日常生活にミニマップを

ゲームをしてる時にふと、「日常生活にもミニマップあったら便利なんじゃないか?」と思ったのでUnityを使ってAndroidアプリとして実装してみました。
具体的に言うと「Webカメラを通して見る世界の左下隅に、GPSで取得した現在地の周辺のGoogleMapが常に表示され続けるAndroidアプリをUnityで作ろう」という話です。

実装の際に課題になったものは、
 - UnityをAndroidでビルドできるようにする
 - GPSで現在地の座標を取得する
 - Android のカメラ画像を表示する
 - GoogleMapsAPIで位置情報に応じたマップを表示して現在地にマーカーをたてる
の4点でした。

UnityをAndroidでビルドできるようにする方法は割愛させていただきますが、私が参考にさせていただいたサイトを載せておきます。

ちなみに私はMinimum API Levelの設定で小一時間程悩みましたが、ここはお使いのAndroidのバージョンに合わせてください。私が使ってるバージョンは4.2.2だったのですが、なぜか4.2ではなく4.1でないと通りませんでした。
f:id:unitymas_CS:20150808001936p:plain
また、Virtual Reality Supportedにチェックが入ってるとMinimum API Levelが変更できないのでチェックを外すことを忘れずに。


次に、UnityでGPSを使った位置情報の取得。
これは「Unityで位置情報を取得 - チラ裏Unity」さんを参照してください。全部書かれてます。


カメラの映像を表示するには、WebCamTextureを使用します。

using UnityEngine;
using System.Collections;
public class WebCam : MonoBehaviour {
	public int Width = 1920; //解像度横
	public int Height = 1080; //解像度縦
	public int FPS = 20;
	void Start () {
		WebCamDevice[] devices = WebCamTexture.devices;
		WebCamTexture webcamTexture = new WebCamTexture(devices[0].name, Width, Height, FPS);
		GetComponent<Renderer> ().material.mainTexture = webcamTexture;
		webcamTexture.Play();
	}
}

このスクリプトをPlaneなりQuadなりにアタッチすればAndroidカメラからの映像を見ることができます。


UnityでGoogleMapsAPIを使うには、WWWクラスを使用します。さらに、GPSで取得した現在地と組み合わせるコードはこのようになります。

using UnityEngine;
using System.Collections;
public class MiniMap : MonoBehaviour {
	GUITexture mapGuiTexture;
	private float intervalTime = 0.0f;
	private int width = 300;
	private int height = 200;
	private double longitude;
	private double latitude;
	private int zoom = 16;
	void Start () {
		mapGuiTexture = this.GetComponent<GUITexture> ();
		GetPos ();
		GetMap();
	}
	void Update(){
                //毎フレーム読んでると処理が重くなるので、3秒毎に更新
		intervalTime += Time.deltaTime;
		if (intervalTime >= 3.0f) {
			GetPos ();
			GetMap ();
			intervalTime = 0.0f;
		}
	}
	void GetPos () {
        //GPSで取得した緯度経度を変数に代入
		StartCoroutine (GetGPS());
		longitude = Input.location.lastData.longitude;
		latitude = Input.location.lastData.latitude;
	}
	void GetMap () {
        //マップを取得
		StartCoroutine(GetStreetViewImage(latitude, longitude, zoom));
	}
	private IEnumerator GetGPS() {
		if (!Input.location.isEnabledByUser) {
			yield break;
		}
		Input.location.Start();
		int maxWait =  120;
		while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0) {
			yield return new WaitForSeconds(1);
			maxWait--;
		}
		if (maxWait < 1) {
			print("Timed out");
			yield break;
		}
		if (Input.location.status == LocationServiceStatus.Failed) {
			print("Unable to determine device location");
			yield break;
		} else {
			print("Location: " + 
			      Input.location.lastData.latitude + " " + 
			      Input.location.lastData.longitude + " " + 
			      Input.location.lastData.altitude + " " + 
			      Input.location.lastData.horizontalAccuracy + " " + 
			      Input.location.lastData.timestamp);
		}
		Input.location.Stop();
	}
	private IEnumerator GetStreetViewImage(double latitude, double longitude, double zoom) {
        //現在地マーカーはここの「&markers」以下で編集可能
		string url = "http://maps.googleapis.com/maps/api/staticmap?center=" + latitude + "," + longitude + "&zoom=" + zoom + "&size=" + width + "x" + height + "&markers=size:mid%7Ccolor:red%7C" + latitude + "," + longitude;
		WWW www = new WWW(url);
		yield return www;
        //マップの画像をTextureとして貼り付ける
		mapGuiTexture.texture = www.texture;
        //ミニマップに透明度を与える
		mapGuiTexture.color = new Color (mapGuiTexture.color.r, mapGuiTexture.color.g, mapGuiTexture.color.b, 0.4f);
	}
}

このスクリプトをGUITextureにアタッチすればミニマップが見れるようになります。


少し(というかかなり)GPSの精度が低いのが問題ですが、これで日常生活にミニマップ機能を追加するアプリの完成です。
ハコスコみたいなやつと一緒に使用すれば日常がゲームの世界になったように感じることができるかもしれませんね。

UnityのVoid OnGUI()についてのメモ

かなり既出ではあると思いますが、GUIの書き方や使い方を忘れてしまうことが多いため自分用のリファレンスとしてまとめておきます。

まずは基本的なテキスト、ボタン表示から。
今回はテストということで、カメラにスクリプトをアタッチしています。

void OnGUI(){
  //(new Rect(左上のx座標, 左上のy座標, 横幅, 縦幅), "テキスト", スタイル(今は省略))
		GUI.Label (new Rect (50, 50, 50, 50), "Hello."); //テキスト表示
		GUI.Button(new Rect(50, 100, 50, 50),"World."); //ボタン表示
	}

f:id:unitymas_CS:20150620224940p:plain

はい、テキストとボタンを表示することが出来ました。


次に、作ったボタンに機能を持たせる方法です。
これは上記のボタンを表示するスクリプトを少し書き換えるだけで出来ます。

void OnGUI(){
		if(GUI.Button(new Rect(50, 100, 100, 100),"World.")){
                        //命令//
            Debug.Log("Hello,World!");
                }
	}

このようにif文で囲うだけでボタンを機能させられます。
今回の場合だとボタンを押すとHello,World!の文字が出ます。


次にフォントサイズや文字の色を変更する方法です。

public GUIStyle textStyle;
public GUIStyle buttonStyle;

void OnGUI(){
		GUI.Label (new Rect (50, 50, 50, 50), "Hello.", textStyle);
		GUI.Button(new Rect(50, 100, 50, 50),"World.", buttonStyle);
	}

このようにGUIStyleクラスを定義して、表示する文字の次の引数に入れます。
そうすると…
f:id:unitymas_CS:20150620230653p:plain
このようにスタイルを変更するインスペクタが作成されます。
あとはこの中身をいじるだけでフォントサイズや文字色の他にも、背景画像やホバーアクションなどの設定もできます。
試しにテキストをフォント50の赤色、ボタンをフォント25にして背景を付けてみました。f:id:unitymas_CS:20150620231919p:plain
フォントサイズや色の変更は出来ましたが、ボタン内のテキストが上手く表示されません。
このような場合は、インスペクタ内のAlignmentを変更してください。
f:id:unitymas_CS:20150620232156p:plain

これでうまく表示されるようになります。
f:id:unitymas_CS:20150620232354p:plain


また忘れがちなものが増えてきたらまとめようと思います。

Webページ作成に役立つjQuery②-親要素のサイズに応じて文字の大きさを変える-

今回は、親要素の大きさに合わせてフォントサイズを変えてくれるjQuery、「jquery.fittext.js」について書いていきます。

FitText - A plugin for inflating web type

 

使い方:

例のごとく、上記リンクからjquery.fittext.jsをダウンロードします。

次に、jQueryはhead内、jquery.fittext.jsはbodyの一番最後で読み込ませます。

要素に対して.fittextを付けることでフォントサイズが可変になります。

文字サイズのデフォルトは要素幅の10分の1になっており、()内の数字に応じて縮み幅を変えることが出来ます。1を基準として、大きくすることでより変化し、小さくするとあまり変化しません。

また、minFontSize,maxFontSizeを用いることでフォントサイズの上限下限を設定することが出来ます。

 

Webページ作成に役立つjQuery①-フッターをページ下部で固定-

幾つかWebページを作ってきた中で、地味に役に立ったjQueryを紹介していきます。

 

初回は、フッターの位置を自動でウィンドウの一番下に設定してくれるjQuery、「footerFixed.js」について書いていきます。

footerをウィンドウ下部に固定する『footerFixed.js』

 

使い方:

まず、上記リンクのページからfooterFixed.jsをダウンロード。

次に、htmlのhead内でjQueryとfooterFixed.jsを読み込ませます。

あとはフッターにしたい(ウィンドウ下部に固定したい)div要素のidを「footer」と指定してあげれば完了です。

 

このjQueryのすごいところは、フッターの位置がウィンドウの大きさより小さい場合はページ下部に固定してくれるという点です。

f:id:unitymas_CS:20150403161307p:plain footerFixed.js使用前

f:id:unitymas_CS:20150403161318p:plain footerFixed.js使用後

jQueryなんて邪道だ!」という人でもない限り、これが一番簡単なフッターの作成方法なのではないでしょうか?

 

 

 

パーティクルに衝突判定をつける

 Unityでゲームを作る際に、火の玉のような魔法のパーティクルを敵に当てることができると見栄えがよくなりますよね!

 そこで、今回はパーティクルに衝突判定をつける方法を紹介しようと思います。

 

まず始めに、パーティクルのInspector内にある「Collision」と、さらにその内部にある「Send Collision Message」にチェックをつけます。

f:id:unitymas_CS:20150219212816p:plain

 

 次に、スクリプトを書いていきます。

 パーティクルに関する衝突判定を記述する際は、OnParticleCollisionという関数を使います。

 上記のように書いてあげればパーティクルに衝突判定を持たすことが出来ます。これで魔法攻撃などがバンバン出せるようになりますね。

Processing for openCVで顔検出をしてみた

学校の授業の一環でProcessing for openCVを使う機会があったので、顔を検出して画像を貼り付けるプログラムのコードをメモしておこうと思います。

まず、Processing for openCVはこちらのgithubから最新のものをダウンロードしてください。

atduskgreg/opencv-processing

 

次に、顔を検出して画像を貼り付けるプログラムのコードを書いていきます。

 

試しにこの画像でやってみたところ...

f:id:unitymas_CS:20141226012339g:plain

 

とても簡単に笑い男コラが出来上がりました。

f:id:unitymas_CS:20141226012355p:plain

 

Processing for openCVを使えばいろんなことが楽に出来そうです。