プロトスプリントリーグに参加した(2023/8)

CyberAgent主催の3days ゲームクライアント向け開発型インターンシップ（通称：プロトスプリントリーグ）に参加してきました。

https://www.cyberagent.co.jp/careers/students/event/detail/id=28721

## インターンのスケジュール
ここでは、事前準備期間についての補足説明をします。詳しいスケジュールは、記事冒頭の公式サイトで確認できます。
インターンシップ開始の1週間前に、各チームとそのテーマが発表され、チームメンバーとの初顔合わせが行われました。この事前準備期間中にコードを書いたり、配布されたリポジトリにpushすることは禁止だったので、私たち￥はこの期間を使って、ゲームの全体像や役割分担を決定しました。
## 成果物
<iframe width="520" height="400" src="https://www.youtube.com/embed/xNJj4ZBHCd8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1349017/3d538281-c739-df99-26f1-444f4cbac95d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1349017/6a77abaf-f69e-66ef-51c2-3ed0463b51fb.png)


### 役割分担
メンバーＡ: パズルピースの挙動、ゲームの流れ、UI周り
メンバーＢ: パズルのシステム、パラメータ調整
ーー私ーー: ステージ・ギミックの自動生成
メンバーＤ:　ギミックの作成、バランス調整
メンバーＥ: プレイヤー・UI挙動、スプライト作成
### 評価
メンターさんからのフィードバックです。
**良かった点**
>全体的に完成度が高く，拡張性が高い。
ステージのランダム要素に違和感が生まれないぐらい馴染んでいた。
コンセプトに沿って３日間で作れていた。
**改善点**
>特定のステージのパターンの時に詰みポイントが発生していた。
ゲームクリアするのが結構難しかった。
WebGLの時にUIが崩れていた。
ゲームクリア後のスコアに対するフィードバック(評価A,評価B...)が欲しかった．
# 作業の振り返り
### 事前準備期間
この期間では、[miro](https://miro.com/ja/)を用いて、ブレインストーミングのKJ法でアイデアを考えました。今回のお題は「組み合わせ」です。出てきたアイデアとしては以下のようなものが出ました。
1. ボタンを組み合わせることで行動する、例えば「ジャンプ＋攻撃」のような動作。
2. プレイヤーが戦車をカスタマイズして対戦する2人対戦ゲーム。
3. 気候変動によって荒廃した世界を探索するゲーム。その場に落ちている物を組み合わせて、新しいものを作る
最初は(3)のアイデアも魅力的に思えましたが、開発時間を考慮すると長期のプロジェクトとなりそうだったため、選外としました。その後、(1)と(2)のアイデアを組み合わせることで、ゲームのコンセプトが決まりました。
**ゲーム内容**
1. ランダムに生成されるステージの全体像を最初に確認
2. パズルのような要素でプレイヤーのパラメーターを設定する
3. プレイヤーを動かし、ステージをクリアする
### インターン1日目
ステージ・ギミックの自動生成を作る上で、初めの手順として地形をランダム生成するスクリプトを作りました。
実装するにあたり事前準備期間中に、2つの案を考えていました。
1つ目の案では、横100ブロックのステージを基に地形と各ギミックの特徴を生成することを想定していました。初めにステージの地形を作成し、ギミックの配置を行うというプロセスでした。ギミックには「厄介度」と「ギミック間の最低距離」という2つのパラメーターを持たせて、それを基にギミックの配置を行う予定でした。
2つ目の案は、横10ブロックのステージテンプレートを複数用意し、これらをランダムに結合してステージを作成する方法でした。
どちらの案も元となるステージは、文字は「1 = タイル、0 = 何もない、N = 針山」のようにで構成され、この文字情報をファイルから受け取り、Instantiateを使ってPrefabを各座標に生成する仕組みとしていました。
```c
1111111111
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000100
0000010100
0001010100
01010101NN
0101010111
```
3日間の開発期間を考慮し、2つ目の案を採用することにしました。1つ目の案はチャレンジ性があり魅力的でしたが、短期間での実装には向かないと判断しました。
**反省点:**
ギミック作成の担当者と十分なコミュニケーションを取ることができず、ギミックの機能についての共通の認識を持っていなかったことは問題でした。私の指示が不十分であったため、ギミックの生成方法が明確に理解されておらず、翌日の統合作業時にギミックのコードの修正が必要となりました。
### インターン2日目
ランダム生成の実装に加えて、マップ情報からギミックも生成されるようにしました。昼からはギミックの機能を担当したメンバーとの統合作業を行い、ギミックの調整を行って統合を完了させました。この夕方の時点で進捗が7割くらいでした。
しかし、スケジュールの把握が甘く、3日目はほとんど作業ができないという情報を知り、かなりのピンチを迎えました。更に夜になってプレイヤーの動きが停止するバグやHP関連のバグが発覚し、メンバー全員で深夜まで修正作業に追われました。スケジュール管理の重要性を痛感しました。
**反省点:**
今回のような短期間でゲームを作る際、中々直らないバグは根本的な解決を追求するよりも、取り急ぎ動作する状態にすることの重要性を感じました。
### インターン3日目
私はメインシーンのBGMを設定し、デバック作業やレベルデザイン周りをしました。
ゲームの提出期限は15:00で、13:30頃にメンターさんがWebGLでのビルド中に私のコード部分でエラーを発見しました。このエラーの原因は、私が担当したステージ・ギミックの自動生成のスクリプトがローカルファイルから文字列情報を読み込む設計になっており、関連ファイルをローカルディレクトリに配置していたことでした。このエラーの存在を13:30に作業チャンネルで知らせられていたのですが、私はビルドしていないから関係ないだろうと思い、エラー内容を読んでいませんでした。14:00にチームメイトからエラーの進捗について聞かれ、焦ってその問題を確認。メンターさんと共にローカルディレクトリの参照をResourcesディレクトリに変更し、提出の30分前には無事エラーを解消し、ビルドを完了することができました。
**反省点:**
WebGLでビルドすると、保存先のパス参照が変更される事を事前に気付くべきでした。
直前のエラーメッセージにはしっかり目を通すべきでした。
## 意識したこと
新しい機能を作る際に、拡張性を持たせることを重視しました。例として、ステージのギミックを生成する際に、任意の大文字のアルファベットから生成するprefabを辞書型で実装しました。これによって、新しいギミックを生成するときにコードを書き換える必要なく、ギミックを追加することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1349017/42a234c5-ec98-bdcc-5af0-589365e9b541.png)
コードの可読性にも特に注意を払いました。42Tokyo入学以前にゲームを作っていた時は、同じ処理のコードを繰り返し書いていたり、コードの可読性を意識していませんでした。しかし、42Tokyoで学んだコード規約を今回のインターンに生かし、関数化や変数のスコープ範囲を意識し、読みやすく効率的なコードを書くことができたと感じています。さらに、テキストの文字情報からマップを生成する部分も42Tokyoで学んだ内容を応用して実装しました。
## 学んだこと
今回のインターンで初めてUnityを用いたチーム開発を経験しました。これまでC言語を使用したチーム開発は2回ありましたが、Unityを用いたものは初めてでした。Gitのコンフリクトを心配していましたが、その点での問題は生じず、スムーズに開発を進めることができて良かったです。この経験を通じて、Unityでのチーム開発のノウハウを学び、自信を持てました。また、Unityの機能やC#の書き方など、新しい知識をチームメイトから学べました。
 ## 最後に
3日間のゲーム開発は非常に大変でしたが、次回も是非参加したいです！