新卒未経験が1ヶ月でARデモゲーム制作

こんにちは id:k-iwadate です。
先月、「Cloudii」は K2 Vision さんと合同でデジタルコンテンツ EXPO 2018 に出展させていただきました。

K2 Vision さんの HP
K2 Vision -about us

展示したものは、ゲームサーバー開発・運用サポートツール「Cloudii Online Solution」と、
それを用いて新卒未経験者 2 人が 1 ヶ月で制作したデモゲームです。
今回の記事ではそのデモゲームの内容や仕組みについてお話したいと思います。

出展概要とデジタルコンテンツ EXPO 2018 についてはこちらからもご覧いただけます。
cloudii.jp

ゲーム概要

どんなゲームかというと、自分が描いた魚を泳がせて釣ることができる AR 釣りゲームです。
描いた魚は削除や上書きが行われない限り、以降毎回登場する可能性があります。
もちろん魚の絵じゃなくても OK です。
長靴と未確認生物と秋刀魚が餌に寄ってくるというカオスな海になるかもしれませんが......
それも含め、プレイした方々の絵次第でさまざまな海になることも特徴の 1 つです。
また、一度も釣られていない新種の魚を釣ると命名ができ、以降釣られるとその名前が表示されます。
釣りですが、ある意味絵心とネーミングセンスが問われるゲームです。

おおまかなゲームの流れは以下のとおりです。

  1. 絵を描き、透過 PNG 形式で保存

  2. 魚登録画面で画像をサーバーにアップロード

  3. ゲームを起動

  4. 画面をタップで海を設置

  5. 頑張って釣り上げる!

  6. 結果画面に遷移

  7. プレイヤー名や (新種の魚の場合は) 魚の名前を入力

  8. サイズ順のランキング画面に結果が反映

ゲームプレイ映像

なんと、からあげアイドルの有野いくさんがインタビューに来ていただいたのですが、
インタビューの中でゲームをプレイしていただいているので是非ご覧ください。

www.youtube.com

クライアントの開発に使用したツール

  • Unity 2018.2.10

  • ARKit 2.0

ゲームの仕組み

それでは、クライアントとサーバーで何を行なっているかをゲームの流れに沿ってみていきます。

データベースについて

まず前提としてデータベースについて説明します。
作成したテーブルは以下の 2 つです。

  • 魚のデータを登録するテーブル (以下、魚テーブルとします) f:id:k-iwadate:20181226104414p:plain

    • id: 1 はじまりの連番
    • name: 魚の名前
    • rate: 出現確率 ※ ガチャ用のカラムですが今回は使用していません
    • user_name: 名付けた人の名前
    • create_time: 作成日時
    • update_time: 更新日時
  • 釣った結果を登録するテーブル (以下、結果テーブルとします)
    f:id:k-iwadate:20181226104746p:plain

    • id: 1 はじまりの連番
    • type: 魚固有の id (魚テーブルの id に紐づいています)
    • size: 釣った魚のサイズ
    • user_name: 釣り上げた人の名前
    • create_time: 作成日時
    • update_time: 更新日時

描いた絵を泳がせる

ペイントツールは ibisPaint X というアプリを使用しました。透過 PNG で保存する機能が付いているので今回のゲームにピッタリでした。

f:id:k-iwadate:20181226182801p:plain

ローカルに保存後、以下の魚登録画面からアップロードします。
試しにウツボをアップロードしてみましょう

f:id:k-iwadate:20181226180418p:plain

保存した画像を選択して「確定」ボタンを押すと、魚テーブルにレコードが追加され、
サーバー上の指定したフォルダーに [ID 値] .png のファイル名で格納されます。
画面が更新されました。

f:id:k-iwadate:20181226180913p:plain

魚データ変更フォームが変わりましたね。
魚の一部データと画像の変更を行うためのフォームですが、魚テーブルの全レコードと、
アップロードされた画像一覧が表示されるので、魚の登録が正常に行われたことが分かります。
実際に魚テーブルを見てみると、レコードが追加されています。

f:id:k-iwadate:20181226183118p:plain

また、画像格納用フォルダーには [ID 値] .png のファイル名で格納されています。

f:id:k-iwadate:20181226185959p:plain

さて、サーバーに反映ができたのでゲームを起動してみましょう。
起動するとリクエストが送られ、サーバーから魚テーブルの最大 ID が返却されます。
クライアントは画像格納用フォルダーのパスと [ID 値 .png] のファイル名を利用し、1 から最大 ID まで (すべて) の画像を取得します。
増えることを考えるとすべての魚は出せないので、出す魚を選定しないといけません。
出す魚の数を固定し、最大 ID の魚は今プレイしている人が描いたものなので必ず出し、その他はランダムで決めています。
魚を選定したらオブジェクトを生成し、動きを持たせます (魚の動きの詳しい説明は次の項目で) 。
これで魚がいつでも泳ぎ出せる状態になりました。
さて、裏側の準備が整ったのでプレイヤーが操作する番です。
ゲーム画面にはカメラの映像が映っているので、平面を見つけてタップします。
ARKit には平面を検出する機能があり、タップした場所を平面と認識したらそこに海が設置されます。
ウツボいますね。

f:id:k-iwadate:20181226122523j:plain

魚の動きについて

  • すべての魚はランダムな動きで X・Y・Z の全座標に動き回るよう設定しています
  • 魚が水面から飛び出た場合は重力を有効にし、水中に落ちていきます
  • ヒット範囲の周りにも範囲を設け、入った魚は一定時間経過か範囲から出るまで針に惹かれた動きをします
  • 針に惹かれた魚は針が大きく動かない限りヒット範囲に入っていきます

竿、糸、針の連動

Unity の Hingejoint という機能で竿と糸、糸と針を繋げています。
これにより個々の重さや動きが影響を及ぼし合うように繋がるため、リアル感を表現することができます。
また、糸と針は水中の浮力と重たい動きを表現するため、空中から水中に入る際に重さを軽くし、抵抗を大きくしています。

魚のヒット判定

Unity の当たり判定機能 Collider を使用しています。
魚と針に Collider が付いており、互いに侵入するとヒット状態になります。
ヒット状態は 1.6 ~ 1.7 秒間継続され、それを超えると魚が逃げてしまうので素早く釣り上げる必要があります。

魚の釣り方

魚がヒットすると端末が振動し、画面に !! マークが出ます (どちらもヒットが外れるまで継続されます) 。
先述のとおり、一定時間経過すると魚が逃げてしまうので、それまでに振り上げることが大前提です。
振り上げ方にも条件があり、振り上げる前の端末の角度から 20 度以上傾けることを条件に設定しています。
そのため、真っ直ぐ上に持ち上げるだけでは釣れません。

お目当の魚を狙う時は画面右下の 2 つのボタンが役立ちます。

  • 竿の奥行きを調整するボタン
  • 針の高さを調整するボタン

動かしたい方向の矢印を押すと、押している間動かすことができます。

f:id:k-iwadate:20181227124551j:plain

結果画面と名前入力

魚が釣れるとその魚の ID をサーバーに渡し、 サーバーは渡された ID で魚テーブルから対象のレコードを探します。
name (魚の名前) カラムの中身をチェックし、空の場合は新種フラグ 1 を、空でない場合は name と user_name (名付けた人) と新種フラグ 0 を返します。
これを元にクライアント側で結果画面を作成しています。
それでは結果画面を見てみましょう。

f:id:k-iwadate:20181227102551j:plain

このからあげはインタビューに来てくださった、からあげアイドルの有野いくさんに描いていただきました!
結果画面には cm 表記でサイズが表示されます。
魚のオブジェクトを生成する際、1.5 ~ 3.0 の間のランダムな数値を元に大きさを指定しており、
その数値を 2 乗して 10 倍した値をサイズとしています。
つまり最小で 22.5 cm 、最大で 90.0 cm となります。 サイズの他にプレイヤー名入力欄もあります。
「あなたが第一発見者です !! この魚に命名できます」とあるように、このからあげは新種のため命名できるようです。
44.3 cm のからあげはたしかに見たことがありませんね......
ちなみに、既出の場合はここに魚の名前が表示されます。
入力が終わったら画面左下の 「NEW START」 ボタンを押下することで、入力した内容やサイズ、魚の ID がサーバーに送られます。
サーバー側は結果テーブルにレコードを追加し、命名が行われていたら魚テーブルから ID で対象のレコードを探し、 name と user_name を更新します。
例のごとくウツボで試してみましょう。
結果テーブルにレコードが追加されています。

f:id:k-iwadate:20181227173547p:plain

また、命名が行われたため魚テーブルの name と user_name も空欄から更新されました。

f:id:k-iwadate:20181227173637p:plain

結果がサーバーに登録されて 1 プレイが終わりとなります。

ランキング画面で確認

ブラウザでサイズを元にしたランキング画面を見ることができるので、見てみましょう。
※ ウツボだけでは寂しいので、魚と結果データを増やしてみました。

f:id:k-iwadate:20181227173209p:plain

結果テーブルは以下のようになっています。

f:id:k-iwadate:20181227173227p:plain

ランキングは結果テーブルの全レコードを取得し、size カラムの値が大きい順に並べ替えることで作成しています。
また、結果テーブルの最大 ID のレコードに new の印付けをすることで、新たに追加されたデータの位置を表しています。
右側の「展示」ボタンでは、釣った魚を見ることができ、3 位まではもれなく王冠が付きます。

f:id:k-iwadate:20181227155411p:plain

まとめ

ボリュームの関係で、特にクライアントの細かい工夫について書ききることは出来ませんでしたが、デモゲームの概要と仕組みをご紹介させていただきました。
私はサーバー側を担当したのですが、「Cloudii Online Solution」というベースがあるため未経験でも簡単に開発を行うことができました。
デモとして作成したゲームではありますが、こうすると面白そうなどご意見がありましたら是非コメントいただきたいです!
今回、特にサーバー側は基礎的な機能のみで、クライアント開発者も今後の課題になる改善点がいくつかあるとのことなので、このゲームを全体的にアップデートしていけたらと思います。
さて、2018 年も残すところ 3 日となりましたが、どうぞ良いお年をお迎えください。
来年も引き続きよろしくお願いいたします。