見出し画像

2ヶ月で2人で音ゲー作った話

苦労したところとか、共同制作こうすれば上手くいったよとか。あとは諸々感想を書きます。総コンAdventCalender2021 10日目の記事です。

作ったゲーム

PCに接続したWebカメラで手の向きを認識して、ランドルト環のノーツを捌いていく音ゲーです。動体視力と反射神経が問われるゲームです。

経緯

2021年、8月初旬。所属サークルでは毎年新入生と交流するために、共同制作が行われます。明大祭での展示発表に向けてゲームを作ることが今年のテーマでした。初めに共同制作をしたい人をDiscordの通話チャンネルに集めて、それぞれ自己紹介をしつつ、自分の作りたいものについての話をしてチームを決めると言った順序です。要するに、同じゲームを作る仲間集めの会ですね。

作りたかったもの

当初、自分の作りたいと言っていたものはこんな感じでした。

スクリーンショット 2021-12-07 16.50.53

ゲームの流れを書いただけなので、めちゃくちゃ雑ですね笑

拘りポイントとしては

・Webカメラを使ったゲームを作りたい

・通常操作すらままならないゲーム、入力が難しいゲームにしたい

という2つの軸がありました。

結果、Mさんが制作に参加してくれることに!やったね。自分のアイデアに面白いって乗ってくれると嬉しくなりますね。(当初誰もいなかったら1人で作ろうとしてた。)

役割分担

Mさん 楽曲制作 ノーツ譜面制作

甘夏 ゲームデザイン全般 実装

という役割分担でやりました。

進捗共有について

今回制作に当たって共有に使ったツールは以下3つでした。

・ScrapBox 新規でProjectを作成

・Slack サークルで使ってるものに新規チャンネルを作成

・Discord 新規サーバを作成

プログラムや実装、アイデアについてのメモはScrapBoxに、定期的な進捗共有はSlackで、会議にDiscodのボイスチャンネルを使う。といった感じで使い分けていました。大体週一で1時間ほど進捗共有と、今後の実装目標とTODOを定めて次の週の課題にするといったルーチンで回していました。

スケジュール

8月初めに発足して日程的にはこんな感じで進みました。これ以外にも適宜デバッグやUIの改善などをやってます。手の認識が実装できないことには話が進まないので実装後、会議(進捗報告会)自体は9月中旬から行いました。

8月23日 Pythonで手の画像から向き認識まで実装できた。

8月24日 Pythonでカメラ映像から手の向き認識を実装完了。

8月26日 Pythonで書き出せず、Pythonで作るのは諦めUnityにシフト。

9月8日 ようやくUnityで手の認識部分だけできる。

9月11日 高速視力検査モードはほぼ完成。

9月16日 第1回会議
       リズムゲームの実装に着手。楽曲の作成をスタート(Mさん)
       
9月23日 第2回会議

9月28日 譜面データの格納を実装。

9月30日 第3回会議
       譜面データ作成Mさんに依頼。

10月1日 曲とノーツの遅延をある程度解消。

10月7日 第4回会議
       曲が殆ど完成(Mさん)。

10月14日 第5回会議

10月16日 第6回会議
        背景のビジュアライザーの追加。

10月21日 第7回会議
        タイトル画面のイラスト完成。
        タップ音と譜面データ片方完成(Mさん)

10月25日 第8回会議
        ランキング画面の作成。

10月27日 紹介動画の作成。

10月28日 第9回会議
        譜面データ完成(Mさん)

10月29日 データの書き出し、無限デバッグ、微調整と修正

10月30日〜11月1日 明大祭

苦労した点

上から時系列順に苦労ポイントを書きます。

・そもそもどうやって手を認識させたらいいんだ

ハンドトラッキング?を実装する上で、機械学習は聞いたことはある程度で、使ったことはありませんでした。なんか高度で難しそうだし、処理重そうだしフレームレートが30くらい出るのか怪しいなって。今回のゲームではリアルタイムに高速に処理をすることが求められます。

結局は、OpenCVという画像処理ライブラリを使って、Pythonで手の画像から向きを検出することをやっている記事があったのでそれを参考に作ることにしました。これなら簡単なアルゴリズムで判定するので恐らく要件を満たすだろうと。


・Pythonで作ったはいいもののゲームを書き出すことができない

上の記事通りにコードを書いて少し修正して画像じゃなく、Webカメラからの映像に対して手の向きをリアルタイムで判定してくれるプログラムは作った。よし、これで上手くいきそうだ。とりあえず最終的には実行ファイルにして配布できるようにしたいから、書き出してみるか。

できませんでした。

なんかよくわからないエラーが沢山出てましたね。(よく覚えていない)。PyInstallerというライブラリを用いてPythonを実行ファイルに書き出そうとしたんですが、何やら書き出すPC環境に入っているライブラリを全て実行ファイルに含めるらしく、OpenCV以外のライブラリも全て書き出されてしまうよう。pandasとかでエラーが出てた記憶が。環境を切り分けてOpenCVのみを入れた環境でやればいいって話なのですがよく分からなかったのでPythonはやめました。

元々Pythonでゲーム作るのはキツそうだなって思ってたので、同時進行で進めていたUnityの方にシフトチェンジしました。Pythonでゲームを作れなくはないけど、デバッグとかUIとかの面で向いているツールではないので。

これは結果的にいい判断でした。大体コードの動きは掴めたのであとはPythonからUnity用(C#)に書き直せばいい話でしたから。(簡単に書き直せる言っていない)結果的にPythonでプロトタイプを作って、Unityで実際に作るという形になりました。


・OpenCV for Unityがインポート出来ない

Unity自体を勉強し始めたのが2021年の7月からなので、アセットって何?状態でした。Pythonで作ったものをUnityで再現するために、OpenCVforUnityというアセットを用いました。同じOpenCVならいけそう!っていう安直な考えです。サンプルの実行だけで3日掛かりました。

このアセット実は1万円します。課金したらやる気になるかな?って思ってアセット自体は8月の最初に買っていますが、使い始めたのは9月に入ってからです。Pythonが書き出しキツイなって分かって初めて使う気になりました。人をやる気にさせるのは詰んだ金額ではなく、逃げられないことによる焦燥感のようです。


・OpenCV for Unityの使い方がわからない

最初はマジで使い方がわからなかったです。ドキュメントを用意してくれてはいるものの、全部英語だし、前提としてOpenCVを使いこなせる人用のドキュメントなのでしょうね。同じ関数はOpenCVの公式に書いてあるから詳しくは説明しないよ。って感じですね。いろんな解説サイトを英語でググって片っ端から書いてみてエラー出てなんでだー!ってなってました。

どうやら色んな言語のためのOpenCVがあるってことに気付き、OpenCVforUnityはJava版のものを書き方がほぼ同じと分かるまでかなり時間が掛かりました。それからはまだスムーズだったと思います。

使い方がわからなかったのには実はもう一つ理由があります。

*VisualStudioのコードの予測変換が自動でONになっていなかった。

最初の頃は気にせず(というか知らなかった)コードを書いていました。エラー出て該当箇所見にいって、Java版のを参考にして書き直してって作業を無限回やってました。予測変換が出ないから、関数の使い方がそもそも違うっていう。Unity2019だと環境的に上手く予測変換が出なかったぽいです。

Unity2018で作ることを決めてプログラムを開いて、自動で入力候補が出てきたときはもう呆れましたね。あぁなんて愚かだったんだろうと。


・当たり判定とノーツを消す実装について

ノーツを消した時にノーツ音が鳴らないバグがありました。

Unityの仕様上、destroyされたobjectについているcomponentは一緒に消えます。ノーツのobject自体に音を鳴らす機能を付けていたので、ノーツを叩いた瞬間音を鳴らすと同時にobjectが消えていたわけですね。これが2日くらい気づけない。

最終的にはノーツを叩いた瞬間にノーツの透明度を0にして、同時に音を鳴らす。音を鳴らし終わった2秒後くらいにobjectを消す。という実装をしました。友達には何そのキモい実装って言われました。


・譜面データの格納方法

private int[,] NotesTimeDirectionPos = 
{
            {1000, 1, 4},
            {2000, 1, 3},
            {3000, 1, 2},
            {4000, 1, 1},
            {5000, 1, 3}
};

こんな感じで {n秒後に, どの向きで, どの位置から} ノーツが来るか。を設定するように2次元配列で定義していました。音楽詳しくないので本来ならMIDIデータ?っていうんですかね。どこの拍にノーツのあるない。で定義できれば良かったんですがそこまで手が回りませんでした。

ここはMさんに編集を頼む箇所だったので申し訳ないな、と思いつつ説明してこの形で依頼しました。難しい……。


・音ズレがいつまでも治らない

ゲームのスタート前に裏でノーツを全て作成してから、曲の再生と時間のカウントをスタート。時間によってノーツが移動すると最初実装していました。が、ズレる。

原因として、Start関数での約300個のノーツ生成に時間が掛かってしまっていて、Update関数での時間のカウントが先に始まってしまっていました。

解決策として、Start関数の最初に enable = false; を入れてUpdate関数を起動を無効。Start関数の最後に enable = true; でUpdate関数を起動。タイムカウントを開始。という方法を取りました。おおよそ上手く動きました。

世に出ているスマホ音ゲーってどうやって実装してるんですかね。何か恐ろしいものの片鱗を味わいました。


・動画のロードに時間がかかるせいで曲が先に流れる

背景の曲のビジュアライザーは実は動画です。そのロードに時間がかなり掛かります。長くて3秒くらい。その間に曲とノーツ移動が始まります。地獄です。これも動画の読み込み終了を書いて制御しました。

それでも曲とズレる。

最初はノーツと曲の開始のタイミング、2つだけの遅延だけを考えていましたが、3つ目の背景動画ともなってくると大分キツイです。Unityには、動画が再生可能かどうかを返してくれる関数がありますが、ミリ秒単位で正確ではない模様でした。毎回実行する度にロード時間が変わります。大体0.5秒ほどズレていましたが、プレイには直接関係しないので見送りました。時間があれば今後改善したい……。


・照明によって手の認識精度がアホになる

アルゴリズム上、カメラ画像の2値化の際にノイズが入ると手の領域を上手く認識できません。ノイズは照明の強さによって大きく左右されます。2値化の閾値を弄ればいいのですが、それに気づけたのは本番3日前。急いで実装しました。本番環境で一度試すのってやっぱり大事です。

アルゴリズムはこの記事で解説しているのでよく分かると思います。


それでもエラーはやってくる

・Windowsで書き出したゲームがフリーズする

前々日にこのエラーが発覚してめっちゃ青ざめました。Macだと動いていたゲームをWindowsで書き出すと、シーン遷移で手の認識がしなくなります。

原因はこれでした。Windows固有のバグ(仕様)やめて欲しい。この方のツイートが無ければ確実に死んでました。ありがとうございます。


・ランキングデータの読み込みエラー

明大祭が3日間あるので、盛り上がるかなって思ってランキング機能を実装していました。データを取り出せるようにテキストデータに読み書きする形を取っていました。

前日に悲劇は起きます。

なんと、サイトで公開できるように Google Drive に置いたデータをDLして起動するとランキング画面でフリーズするではないですか。

この方の記事のお陰で解決できましたが、公開直前にこういう不足の事態起こるのは常なんですかね。2連続は流石に疲れました。

明大祭当日

軽微なバグはありましたが、30分くらいで直せるものでした。それ以外は全く問題なく動作したのでデバッグ頑張って良かったと思える出来でした。

終わりに

8月初旬から作り始めているのになんで2ヶ月なんだ。というのは8月中は別件で忙しく殆ど制作できなかったので、実質的に9月から11月までの2ヶ月としました。

ScrapBoxは使い倒しすぎて今見たら64ページになってました……。基本的に自分しか書かないのでそう考えるとすごい量ですね。毎日何かしら書いてるっていう。確かに何か思いついたら全部ここに書き殴ってましたね笑。

約2分30秒の長さのノーツ譜面を2曲分頼んで、完璧に仕上げてくれたMさんには感謝しかないです。結構ノーツの設定方法も複雑だったし、何より一個一個設定するのはかなり大変だったと思います。

完成したゲームの楽しさの大部分は楽曲のクオリティとノーツの配置具合が占めていました。最高の創作をしてくれました。

そもそも「リズムゲームにしたら面白そうですね!」っていうアイデア自体Mさんの賜物なのでMさんが居なかったらここまで面白く作れていなかったと思います。視力検査だけして終わりっていうゲームでしたね。感謝です。


最後に、共同制作に大事そうなことを伝えて終わりにします。

①進捗報告はこまめにしましょう。

現在ここまでできて、いつくらいまでにこれをやる予定です。まで言えると最高です。

②締め切りは守りましょう。

自分の作業が遅延することで全体が遅延したりします。期日までに仕上げられる最高のクオリティを出しましょう。ブラッシュアップできる期間を設けられるといいかもです。

③感謝を忘れないようにしましょう。

同じチームの方はその方のベストを尽してくれています。大抵の創作物はその人にしか作れません。感謝をしましょう。同じようにあなたの創作物もあなたにしか作れません。頑張りましょう。

いいなと思ったら応援しよう!