これちのPost-it

技術ネタをペラペラと

Tangoを使って3D版ARテトリスを作ってみた

今回作ったデモ

www.youtube.com 今回、Tangoを使って3D版ARテトリスを作ってみました。こちらがデモの動画です。

動機

最近ARに興味がありTangoで何か作ってみたいなーと思っていたらふと、今まで2次元でやっていたゲームを3次元に拡張して現実空間でやってみたらどうなるんだろう?と思い、作ってみました。
今回の記事では今回作ったデモのアプリ紹介をメインに行いたいと思います。
実装についてはおいおい記事にまとめます。 ちなみに、まだまだバグや見た目を直していかないといけない部分があるため、完成品とは言えませんが動くもものは出来たので。

動作環境

Lenovo Phab2 Pro (Tango搭載, Android 6.0)
Unity 5.6.1f1

ゲームスタートの流れ

ゲームを起動すると画面中央に、ゲームステージを選択するUIが表示されます。
f:id:korechi:20170801021745p:plain
その後ゲームを開始したい地点を決めたらスタートボタンを押してゲーム開始。

操作方法f:id:korechi:20170801021838p:plain

ブロック操作は画面左にある上下左右ボタンと、画面右にある矢印下ボタンで行います。(見づらくてすみません)
上下左右ボタンを押すとその方向にブロックが移動します。
画面右のボタンを押すと一番下までブロックが移動します。(ここらへんはスティックなどを使ってもっと分かりやすく出来そうかも)

スコア表示

ステージ上にスコアが表示されます。
同時消しをするほどスコアは増えやすくなります。

気づいたこと

さすがTango。一度ステージを作るとほとんどぶれないです。
また、後ろから回り込んで見てみても問題なくブロックを見ることができます。
それに、Unityを使えば比較的簡単にAR対応アプリを作ることができるます。

反省点

ブロックがどこに落ちるか少し分かりにくく、予想外のところでブロックがひっかかってしまうことがよく起こる。

良かった点

通常のテトリスに縦方向を加えたことによりゲームの難易度が多少あがって面白くはなった(気がする)。
作り込めばもう少し面白くなりそう。
しかし、ARにしただけでは面白さという点で+αとなるものは少ないと感じた。 そのため、もしAR向けゲームを作る方がいらっしゃれば、「ARにするだけではなく、ARの特色を活かしてゲームの面白さを引き出す」ことを心がけていただければ幸いです。僕も心がけます。

最後に

AR向けアプリを作るのは楽しいです。
作ったものが現実世界でグリグリ動いてくれるのはなかなか新鮮ですので。
もしTangoアプリ開発に興味を持った方がいらっしゃれば、
korechipostit.hatenablog.com
に簡単なTangoアプリの作成方法がのせてありますので読んで見てください!

Unityでログインボーナスのようなスクリプトを書いた

ログインボーナスのようなものを今回実装したいと思います。
これはつまり、アプリを起動した時に日をまたいでいたら一度だけ処理を行うものです。何となく便利そうですよね。
これをUnityで実現するためには、
1. 日付の取得
2. 日付をデバイスに保持
3. 取得した日付とデバイスに保持された日付を比較
この3つの処理が必要です。
それぞれの実装方法を紹介したいと思います。

日付の取得

UnityのDateTimeというクラスを使います。

使い方

Datetime now = DateTime.Now;

こうやって時間を取得します。また、

int todayInt = 0;
todayInt = now.Year * 1000 + now.Month * 100 + now.Day;

このようにすることで年月日をそれぞれ取得できます。now.Year等の型はintです。
時間も簡単にとれるみたいです。
この例では、例えば2017年7月13日の場合、todayInt=20170713という値が格納されます。
こうやって日付をint型に変換することで、年月日の比較が簡単に出来ますね。

日付をデバイスに保持

値をUnityからデバイス(PCやAndroid)に保存するためにはPlayerPrefsというクラスを使います。
このクラスはデータのセーブ、ロードが行えます。
具体的に保存される場所や形式はここを見れば分かります。
例えば、Android端末では /data/data/pkg-name/shared_prefs/pkg-name.xml に保存されるようです。
保存される値は、KeyとValueのペアです。
例えば、Keyを"Date"とし、Valueを20170713とするペアが考えられます。

使い方

まずは下にPlayerPrefsクラスの使い方の例を書きました。

bool isDateExist;
int todayInt;

isDateExist = PlayerPrefs.HashInt("Date");   // Dateが保存されているか確認する。あったらtrueが返る
PlayerPrefs.SetInt("Date", 20170713);  // Dateを保存
todayInt  = PlayerPrefs.GetInt("Date");        // Dateの値を取得

これをうまいことコードとして書くとこのように書けたりします。

if (!PlayerPrefs.HasKey ("Date")) {
  Debug.Log("Dateというデータが存在しません");
  PlayerPrefs.SetInt ("Date", todayInt);
} else {
  if (todayInt - PlayerPrefs.GetInt ("Date") > 0) {
    PlayerPrefs.SetInt ("Date", todayInt);
    Debug.Log("次の日になりました");
  } else {
    Debug.Log("今日すでにログインしています");
  }
}

取得した日付とデバイスに保持された日付を比較

これはもうまとめてサンプルコードを載せちゃいます。

こんな感じです。参考になれば幸いです。

Tangoを使って空間に文字を入力できるようにしてみた

今回、Tangoを使って空間に文字を入力し、その場所に文字が表示されるものを作ってみました。
今回作ったものはこちらです。
f:id:korechi:20170623234816j:plain
スマホの画面上のどこかをタップするとキーボードが出現し、文字を入力するとタップした場所に文字が表示されます。
f:id:korechi:20170624000950j:plain
ベッド、クッション、カーテンという文字を空間に入力してみました。別の方向にカメラを向けてカメラを移動させても
f:id:korechi:20170623234759j:plain
こんな風にちゃんと同じ場所に文字が表示されています。
割といろんな用途がありそう?
今回の記事ではその手順を紹介したいと思います。

使うもの

Phab2 Pro
Unity
Tango SDK for Unity←ない人はここからDL

環境セッティング

Tango向けにUnityでアプリがビルドできる方は環境セッティングはスルーして構いません。

前提

Unityがインストール済み
UnityでAndroid用apkがビルドできる(できない人はここを参照)

TangoSDKのインポート

まずTango SDK for UnityをUnityにインポートします。
インポートが終わったら下のような構成になっているはずです。
f:id:korechi:20170623235201p:plain:w300

アプリを作る

プレハブの設置

Assets/TangoPrefabsにある、TangoManager、TangoPointCloud、TangoCameraをhierarchyに配置します。
f:id:korechi:20170623235326p:plain MainCameraは使わないので、非Activeにするか削除しましょう
基本的にこれらのPrefabはInspector上でぽちぽちするくらいで、中のスクリプトは基本いじらないと思います。
これらのプレハブがHierarchyに配置されていないとTangoは動作しませんので注意が必要です。

GameControllerの配置

Hierarchyでcreate -> create EmptyでGameControllerを作成。
Projectビューでcreate -> C# ScriptでGameController.csを作成し、上のGameControllerにアタッチ
GameController.csの中身はこのようになっています。

やってることは大きく2つ。
1つは、タッチされたらスマホのキーボードを開く
2つ目は、キーボードの入力が終わったら入力された文字を表示する
詳細はコードを読んでいただければと思います。

TextMeshを用意

今回はTextを表示させるものとして、一度create EmptyでMemoという空のGameObjectを作り、それにTextMeshというコンポーネントを追加しました。
f:id:korechi:20170624000436p:plain:w300
そしてそれをPrefab化し、ソースコード上でInstantiateしてtextを書き込む、といった形で使用しました。
文字サイズの調整は以下のサイトを参考にしました。
www.clrmemory.com
その際、GameControllerのInspectorのText ObjectにMemoオブジェクトのPrefabを適用させることを忘れないでください。
f:id:korechi:20170624000620p:plain:w300
イメージとしては、

public GameObject 3DText;  // Prefabを持ってきたもの
private GameObject m_text; // PrefabをInstantiateしてできたもの

m_text = Instantiate(3DText, position, Quaternion.identity);
m_text.GetComponent<TextMesh>().text = "hogehoge";

な感じです。これでテキストにhogehogeという文字が表示されます。

完成

あとはビルドして終わりです。
今回は、空間に文字入力してそこに文字を表示させるだけのものを作りましたが、次はアプリが再起動しても同じ場所に文字が見えたりするようにもしてみたいです。

korechi's diary からブログ移行

korechi’s diaryを書いてた「これち」です!
以前のブログは、大学院生の時に必要となった知識を「自分のため」にメモしておくという目的で書いていました。

これからは、もっと面白く・役に立つ技術を分かりやすく書いていくことで「他の人」にも読んでもらえたらなと思いました。
そこで「これちのPost-it」として新しいブログを立ち上げました。

タイトルの通り、得た知識をPost-itのようにぺらぺらと書いていきたいと思います!
しばらくはAR/VRのネタが中心になるかと思います。
よろしくお願いします!