七月七日、七夕の日に、CrossOver GameJam 04に参加してきましたー。
ゲームジャム遠征は京都や岡山など近場にはよく訪れていますが、東京まで遠征したのは久々です。
折角遠征するのですから、楽しんでいきますよー。
この記事にはUnity5.6.2f1を使用しています。
前準備
CrossOver GameJamとは、
http://www.crossover.link/cogj04/www.crossover.link
どうにもゲームには使わなさそうなイケてるテクノロジーを使ってゲームを作る、というコンセプトのゲームジャムです。
という一風変わったゲームジャムです。
ちなみに、今回のテーマは「顔認識」!
わー……、使ったこと無ぇー。どうすればいいのかもわかんねぇー……。
ただ聞く話によれば、Microsoft社さんのFaceAPIを使えば、ど素人の僕でも簡単に顔認識が使えちゃうとのことです。あとでテストせねば。
顔認識ということは、カメラを使って撮影した画像を使うことが考えられます。
その辺の準備と仕込みは、前回のブログで確認しているからきっと大丈夫、大丈夫なはずだ。
さあ、というわけで、午後半休を取った会社を後にして、東京に向かいますよー。
7/7 顔合わせ
さあ、着きましたよ。東洋の魔都、東京に。都会ですねー。
とりあえず、この渋谷の交差点の反対側にいくにはどうすればいいのやら。集合時間ギリギリなんですけど。
なんとか遅刻せずに会場に到着しましたよ。
会場では司会者と思わしきお姉さんがHololensを掛けてお話していましたよ。
Hololensしたまま司会している #cogj pic.twitter.com/nic6NtitLt
— ずんずんさん🍀 (@cafecake_u) 2017年7月7日
都会の人は皆Hololensを掛けて生活しているのでしょうか。東京怖い……。
そんなこんなで今回のゲームジャムで共に戦うチームメンバーが決まりました。
プランナー一人、エンジニアは僕を入れて二人の合計三人の少数精鋭チームですよ!
何でも出来そうな気がしてきた!
ゲームジャムの本番は明日からなので、今日はこれにて解散なのですが、チームでの親睦を深めるためにアルコールを注入しに行きますよー。
んー、お酒が美味しいですね。
えっ、こんなに遅くまで飲んで大丈夫ですかって?
大丈夫ですよ。会場の近くにホテルを取っていますから何とでもなります。遅刻なんてしませんよ!
飲み終わって明日に向けて解散しました。
明日は会場に08:50に集合です。
ホテルに戻ってすぐに横になろうかと思いましたが、折角なのでFaceAPIのデモをテストしてから寝ることにしましょう。
この辺はあとで別件としてもブログにまとめなければ……zzz。
7/8 そして寝坊フラグ成立
目が覚めた。
まだ随分と部屋が暗い。まだ夜明け前だろうか。時計を見てみよう。
09:30。
もう一度、時計を見てみよう。
09:30。
会場集合時間は8:50。やってしまった。
くっ、このホテルの部屋は日の光が入らないタイプの部屋だったか。
とりあえずすぐにでも会場を向かわなければ!
しかし寝坊をしたことなんて何時以来だろうか。
思い返してみても、学生時代に日勤と夜勤のバイト掛け持ちしていた時ぐらいだ。
どんなに会社でフワフワ働いていたとしても、寝坊だけはしたことなかったというのに!
とりあえず、皆に連絡しなければ! うーん、どう釈明したものか。
うけたみたいだ。よかった。
みんないい人で本当に良かった。
さあ、少し遅れましたが作業を開始しましょう。
失敗を気にしても仕方ありませんしね、前向きに行きましょう!
作成を目指すゲームとして、画面奥から歩いてくるキャラクターに対して、ユーザーが特定の顔の表情をすることにより、歩いてくるキャラクターがこっちに寄って来たり、スルーされたりするというものを作っていきます。
とりあえずキャラクターはUnityちゃんを使用しましょう。
さあ、昨日作ったFaceAPIのテストと、WebCamTexture
を使って撮影したユーザーの顔データから感情パラメータの取得にチャレンジしますよ。
WebCamTexture
の情報をバイナリデータに変換して、FaceAPIにぶん投げる。
あとはしばらく待っていれば、顔認識情報の詰まったJsonデータを受け取ることが出来ます。
あら簡単!
あとはこのJsonデータを解析すればいいのですが、Jsonかぁ……。
僕はJsonのパースにはUnityのJsonUtility
しか使えないんですよねー。
でも受け取ったJsonはフォーマットがちょっと違うみたいで、JsonUtility
のパースで失敗してしまいます。
うーん、どうしよう。
この場で、MiniJSONやLitJSONを勉強するのは時間がもったいないしなぁ。
そもそもJsonUtility
のパースで失敗している理由はなんなのだ。
そうか最初に角括弧を使っているからか。だとすれば……、
private void OnReceiveFaceData( string i_json ) { // 顔認識の情報を受け取るよ // ただし角括弧、テメーはダメだ。 // ※ 良い子はマネしないでください。 i_json = i_json.Replace( "[", "" ); i_json = i_json.Replace( "]", "" ); var faceData = JsonUtility.FromJson<FaceAPIData>( i_json ); }
よっしゃー、パースに成功したー。
角括弧を亡き者にすることで、JsonUtility
のパース出来るフォーマットに変更じゃー。
仕事じゃ絶対にできない荒業じゃー。
いいんです、とりあえず動いているようですし。
ゲームジャムのような短期決戦の場合には特に問題にはならないでしょう。
初日午前中進捗ですよー。
— うら干物 (@urahimono_maigo) 2017年7月8日
圧倒的進捗!
#cogj pic.twitter.com/1tjnZNS4YY
その後、順調に作業は進んでいきました。
撮影した顔写真から感情を取得し、その取得されたパラメータによって、歩いてくるUnityちゃんの行動が変わるようになりました。
とても早いペース作業が進んでいったので、余裕のある状態で初日のα版発表に望むことができそうです。
そして、α版発表会が始まりました。
発表までの時間に余裕があったため、テストもしっかり行いました。
これはいいプレゼンになりそうですよ!
画面奥からUnityちゃんが歩いてくる、それに対して僕は満面の笑顔をつくる。
するとUnityちゃんがこちらの方に歩いてくる。
問題なく動いています。
再び画面奥からUnityちゃんが歩いてくる、それに対して僕は悲しい表情をつくる。
これでUnityちゃんはこちらに来ずに、あらぬ方向に歩いていくはず……、あれ、ゲームが止まった。
ど、どういうことだ。テストした際にはこんな現象は起きなかったはず。
もう一度、ゲームを再起動しておこなってみよう。
今度は笑顔をつくって……、今度は一発目でゲームが止まった。
な、何が起きているんだ。何故またJsonのパースエラーが起きるのだ。
考えろ……、考えるんだ。
少なくともテスト時には問題なく動いていた。
そして今は、ゲームが動作するときと止まってしまうときがある。
そう、ここだ。
必ずゲームが止まるというわけでもないんだ。きちんと動作したときもあった。
この発表会のときとテスト時で、何か違うところはないだろうか。
……はっ、これだ! これがテスト時と現在とで違うところだ。
すみません、エンジニアさん。立ち位置をもう少し左の方にずれていただけませんか。
ゲームが停止しなくなったー。
そうなのだ、ここがテストしたときと違うところだったのだ。
テストは各個人のパソコンで各自がテストしていた。
ただ現在の状況は、発表用のパソコン一台の前に、チームメンバー全員がいる状態だ。
そのため、顔認識が複数人に対して行われている状態だ。
とうぜん複数人の情報がある場合は、取得できるJsonデータは複数人分の情報が含まれたものとなる。
無理やりJsonはフォーマットを改造したせいで、複数人分の情報がある場合は、Jsonのパースに失敗していたのだ。
くっ、結局サボったつけを払う羽目になってしまったか……。
α発表会の際は、うまくプレゼン力で誤魔化してもらえたけど、あとで対応しておかねば。
とりあえず面倒なので、複数人の情報だった場合は処理を弾いてしまえ!
多くの支持を得たアルファ版!
— うら干物 (@urahimono_maigo) 2017年7月8日
顔認識機能を入れているけど、僕のイケメンフェイスを晒すわけにはいかないからビスコで代用だよ!
#cogj pic.twitter.com/Qdsfq1jXjt
そんなこんなでα発表会終了。
周りからも好評でした。よかったよかった。
ゲームの基礎部分はこれで出来たので、明日はゲームのブラッシュアップに全てつぎ込みますよ。
というわけで、α発表完了記念として、今日もアルコールを注入しますよ。
えっ、こんなに遅くまで飲んで大丈夫ですかって?
大丈夫ですよ。僕は同じ過ちを繰り返すほど愚かじゃないですよ。はっはっは……。
7/9 最終日
目が覚めた。
時刻は3:00。
早いよ!
まだ太陽すら昇ってないじゃないか。
もう一眠りしよう。
目が覚めた。
時刻は5:00。
まだ早いよ!
集合は8:50なので、7:00に起きれば何とかなるはずさね。
もう一眠りしよう。
目が覚めた。
時刻は8:00。
ギリじゃねぇか!
今日はホテルのチェックアウトとかしなくちゃいけないから、そこそこ時間が掛かってしまいそうだというのに。
ああ……、結局今日もダッシュじゃないか!
現地に集合。
時刻は8:49。
1分前集合だ。ぜーぜー。
と、とりあえず遅刻フラグは折ることには成功したようだ。
さあ、今日は最終日。頑張っていきましょう。
しかし、今日のプランナーさんはポスター作りや動画作りなど提出物の作成に忙しそうですね。
うちのチームにはデザイナーさんがいませんから、いろいろと細かいものを作ってもらわねばいけなさそうです。
こうなれば今日は、僕らエンジニア二人でブラッシュアップしていくしかありませんね。
頑張っていきましょう!
えっ、歩いてくるUnityちゃんの表情に合わせてプレイヤーも表情を作るようにしたいですって?
確かにこれは昨日三人で話し合って決めた仕様ですね。分かりました作っておきますよー。
えっ、フィールドが地面の板ポリ1枚では寂しいですって?
それでしたら、無料のアセットを使ってフィールドを豪勢にしましょう。
この辺のことは話し合われていませんが、プランナーさんは忙しそうですし、我々の方で追加してしまいましょう。
えっ、フィールドは豪華になったけど、空が同じで寂しいですって?
んー、そうですねー。
ではスカイボックスのテクスチャを、ゲームを繰り返していくとしていると変化していくようにしましょう。
ついでにライトの明るさも調整しておきますよ。
えっ、無音だと何となくゲームが寂しいですって?
そうですねー。それでしたらUnityちゃんのデータの中に音声データがあったはずです。
それを組み込んでいただければ、にぎやかになるかと。
あとついでにリザルトの得点発表時にドラムロールの音も追加していただけるとうれしいですー。
順調にどんどんゲームがブラッシュアップされていっていますね。
おや、どうしました、プランナーさん。
なるほど、ポスター作成のためにゲーム画像が必要なんですね。
ただ、現在いろいろと改良中ですから、ゲームが突然動かなくなってしまうタイミングがあるかもしれません。
というわけでこのプロジェクトで新しくブランチを作りますよ。
そちらのブランチのプロジェクトを使っていただければ、安定したものが遊べるかと思います。
マスターブランチは我々が作業しているので、触るとあぶないかもしれません。
というわけで、マスターブランチは触らないでくださいね。
よし、ブランチも分けたし、ガンガンブラッシュアップしていくぞ!
えっ、この顔認識APIの情報取得を待っている間にUnityちゃんの動きが一瞬止まってバグっぽいですって?
なるほど、確かにこれはバグっぽいですね。
まあ、ゲームの進行には影響なさそうですが。
エンジニアとしてバグを放置するわけにはいきませんよね。
新しい仕様を追加するより、バグの修正を優先しましょう。
たとえゲームの進行に一切影響がなさそうなバグだったとしても!
おや、どうしました、プランナーさん。
なるほど、そろそろゲームプレイ動画を作成する必要があるんですね。
それでしたら、新しくブランチを作りますよ。
マスターブランチは我々が作業しているので、触るとあぶないかもしれません。
というわけで、決してマスターブランチは触らないでくださいね。
残り作業時間も少なくなってきました。
最後の追い上げが必要ですね。
えっ、そもそもこのFaceAPIはどんな顔なら認識するかですって?
んー、そうですね。どうなっているのでしょうね。
少なくとも手元にあったビスコの子供の顔は認識してましたね。
では手書きの顔なら認識するか試してみましょう。
あっ、プランナーさん。そこにあるポストイットの束を取ってください。
……。
んー、子一時間試してみましたが、手書きでは中々「顔」だと認識してくれないみたいですねー。
おっと、もう作業時間終了のようですね。
しまった、最後の追い上げ時間が、似顔絵コーナーの時間になってしまった。
いろいろあったけど、最終的に出来た作品がこちら。
これが僕らのチームの二日間の集大成さ!
— うら干物 (@urahimono_maigo) 2017年7月9日
クロスオーバーゲームジャム堂々三位の圧倒的クオリティ! #cogj pic.twitter.com/3GcjeL4yPc
他のチームの作品を見てみると、ランキング機能など、繰り返しプレイを楽しめるようになっているみたいですねー。
僕らもバグ直しよりそっちを優先した方がー……、いいえ、僕たちが楽しかったのでそれでいいのです。
後半プランナーさんをおざなりにしすぎた気がー……、いいえ、そんなことはありません。皆楽しかったに違いないのです。
少なくとも僕はとても楽しいゲームジャムとなりました。
有意義な週末が過ごせましたよ。
悔やまれることがあるとすれば、このゲームジャム後に懇親会があったのですが、大阪に当日中に帰らねばならない都合上、途中退席してしまった点ですね。
月曜午前半休とっておけばよかったなー……。
次回も是非参加したいものです。