うまい棒モンスター

https://github.com/Kazamidori-flavor/UmaibouMonster

Swift

GitHub

C#

Unity

Rust

うまい棒で作成した3Dモデルで遊ぶ 1vs1 の対戦ゲーム

カシュー

Yuto Terada

kaja

hirose

gohan5858

推しアイデア

うまい棒を彫刻してバトル! うまい棒彫刻へのこだわりがゲームを左右する。

作った背景

うまい棒といえば10円!それが今や値上げを繰り返し15円。 「15円でもうまい棒を買いたい!」と思えるような付加価値をゲームで提供します。

推し技術

うまい棒 めんたい味

プロジェクト詳細

事前準備

うまい棒彫刻(3Dモデル

image

image

image

アーキテクチャ図

image

シーケンス図

image

繋ぎ合わせ

image

image

がんばったところ

本プロジェクトでは、各メンバーが専門領域を持ち、サーバーサイドからクライアントサイド、モバイルネイティブ連携に至るまで、多岐にわたる技術課題に取り組みました。

1. サーバーサイド(同期通信・モデルアップロード担当)の頑張りと工夫

プレイヤーの同期通信やモデルのアップロード機能を担当したエンジニアは、主にシステムの堅牢性とスケーラビリティに注力しました。 また、github worktree ✖︎ antigravity(Agent manager)で同時並行で多くのタスクを実施できるように仕様の固めを頑張りました。 さらにデプロイ外部サービスを使わず、自前のサーバーにデプロイし、CI/CDも組みました。

担当領域技術的な工夫・頑張った点苦労・選択のポイント
プレイヤー同期通信同期通信にはWebSocketsを採用し、無難かつ確実な選択肢を取りました。複雑な通信フローをチームで共有するため、シーケンス図を非常に詳細に書き上げ、共有の労力を惜しみませんでした。
モデルアップロードリクエストを受け、DB(データベース)にデータを保存し、パスを管理するフローを構築しました。データベースにはSQLiteを使用。頻繁なアクセスがないため、あえて重量なシステムを避け、軽量なSQLX(ノンORM) を選択することで過剰なスペックになるのを防ぎました。
基盤構築バックエンドにはRustのActixを採用し、100組、1000組の同時接続にも対応できる高い処理能力を持たせました。CI/CD環境を整備し、メインブランチにプッシュするだけで自動でビルド・デプロイが実行される体制を確立しました。

2. サーバーサイド(ファイル変換・マッチング担当)の頑張りと工夫

USDZファイルをモンスターのパラメーター取得やGLBファイルへの変換を行うAPIの実装、およびマッチングシステムの構築を担当しました。

担当領域技術的な工夫・頑張った点苦労・選択のポイント
AIパラメーター生成スキャンされたUSDZファイル(またはそのモデル)を、ゲームで使用するためのモンスターのパラメーターに変換・評価する処理を担当しました。具体的には、AIに写真(モデル)を投げ、その評価に基づいてパラメーターを作成させていました。パラメーター確認のため、サーバー側でウェブサイトを作成し、テスト用にローカルレプリカを作って確認作業を行いました。
開発効率の向上AIを積極的に活用しました。具体的には、GPT-3と、当時最新だったアンチグラビティのエージェントマネージャーを組み合わせて使用し、複数の作業を同時並行(並列)で実行できるように工夫しました。作業完了後に通知が飛ぶように設定することで、高速に実装し、レビューを回すことができ、同時並行でさまざまな実装を高速に行えました。
ファイル変換・API連携USDZファイルをGLBファイルに変換するAPIを実装し、UnityとサーバーAPIの連携(通信対戦・マッチング)を担当しました。

3. クライアントサイド(ローカルストレージ・GLB読み込み担当)の頑張りと工夫

ローカルのストレージ管理、特にGLBファイルの読み込みと表示を担当しました。

担当領域技術的な工夫・頑張った点苦労・選択のポイント
3Dオブジェクトの表示スキャンされたUSDZがサーバーでGLBに変換された後、ストレージに入れられ、それをUnity側で参照・表示する仕組みを構築しました。最も難しかったのは、3Dオブジェクトを一度(ワンタイム)で取得し、画面に映すという初期段階の実現でした。最終的にGLBというフォーマットにたどり着くまでの道のりが長く、苦労しました。

4. ゲームクライアント(Unity)の頑張りと工夫

Unityを用いたゲームサイド全般の実装を担当しました。サーバーやモバイルの知識がなかったため、設計とアーキテクチャに最大限の工夫を凝らしました。

担当領域技術的な工夫・頑張った点苦労・選択のポイント
アーキテクチャ設計責任分離を強く意識し、多数のAPIトリガー(呼び出し元の受け皿としてのScriptableObjectなど)を準備しました。処理とデータを完全に切り分ける設計を採用し、データが切り替わると自動的に処理が回り、UIに反映される仕組み(MVPアーキテクチャ、リアクティブプロパティ)を実装しました。

今回はオブジェクトをあらかじめ用意しておき、それにデータを持たせると言った一般的なゲームとは異なり、パラメーターだけでなくモデルすらも新規で生成されるゲームであったため、モンスターのパラメーターやモデルのリストなど、数多くのパラメーターの参照タイミングや生成タイミングを管理し、正しく反映させることに苦労しました。

5. モバイルエンジニア(3Dスキャン連携担当)の頑張りと工夫

UnityとiOSネイティブ機能(Swift)を連携させ、現実世界の物体をスキャンしてオブジェクト化し、Unityに表示する部分を担当しました。

担当領域技術的な工夫・頑張った点苦労・選択のポイント
ネイティブ連携UnityからSwiftのiOSスキャナーAPIを呼び出し、スキャン結果をUnityに表示する一連の流れを構築しました。UnityからSwiftを直接呼び出すことができないため、間にObjective-C++というブリッジコード(受け渡し役) を書かなければならず、これが非常に面倒で難しかったです。
UIと連携Swift UIを使いたかったため、UI Kitのビューを作成してからSwift UIのビューを作るという複雑な手順を踏みました。スキャン後、どのタイミングでもUnity側に値を渡せる仕組みを実装する必要があり、Unity側の特殊な「文字列で関数名を書いて実行する」という機構を利用しました。

感想

ハッカソン開発での繋ぎ合わせ箇所は多くとも、(int)(メンバーの人数 / 2) くらいにしとかないといけないなぁ

カシュー

@game_game_nuts