サークルでVRコンテンツ開発をしてみた

## 1. はじめに

本記事は三重大学 計算研 Advent Calendar 2019 最終日です。

大学4年の@inamasu、M1の@kimarianです。

計算研はプログラミングや数学が好きな人が集まって情報共有したり競プロに参加したりといった活動をしており、公認サークルになってから今年で4年目にあたります。

最初はメンバーも情報工学科生ばかりで、こじんまりと活動していました。
ですが、近年は工学部だけでなく文理関係なくメンバーに加わり、少しづつですがサークルの規模も大きくなってきました。

計算研では、学園祭にてプログラミング関連で学術展示を行っています。
最初はLTをしてみたりと試行錯誤してきましたが、昨年度、数人で制作したVRコンテンツを展示したところ評判がよく、想定以上の多くの人にVRを体験してもらえました。

そこで、今年はより大規模に、サークルメンバーの多くが参加して合計10人以上(内半分は1年生)でVRコンテンツ開発をしました。

その際の開発の流れやツールなどの振り返り、来年にむけての反省を行っていきます。

### チームメンバーの雰囲気

10人以上で共同で開発するということで、バージョン管理システムを用いた開発は必須でしたが、1年生や他学科などgitを使ったことのない人も多いので(というか情報工学科でもgitの使い方は基本学ばない)、学習をして足並みを揃える必要がありました。
そこで、学習用の資料や手順を作成して「学習タスク」とし、必要な人には取り組んでもらうようにしました。
(gitを用いたことについて詳しくは、[大学のサークルでGitbucketとGitを使ってゲームコンテンツをチーム開発をしてみた](https://qiita.com/kimarian/items/d95eda606eae13927145))

作業の分担としては、1・2・3年生に、内容の企画、仕様など「VRコンテンツの内容」の決定をお願いし、4年、M1は開発の進行や技術的なサポートをする、といった方針で分担しました。

* 1・2・3年生
 * 企画案作成
 * 仕様書作成
 * 使用BGM選定
 * イラスト、テクスチャ制作
 * モデリング
 * プログラミング

* 4年・M1
 * 学習用資料の整備
 * 設計
 * プログラミングのサポート
 * モデリング
 * プログラミング
 * gitリポジトリ壊れたときのお助け係 (@mouri111さんありがとう)

といった形です。
もちろん、企画や仕様、開発ロードマップを考える際はみんなで相談して決めていきました。アンケートでみんなの意見を取り入れたりして、なるべく学年関係なくフラットに意見してもらえるよう心がけました。


## 2. 作ったもの
今回、最初にコンペを行い、２つの企画を採用しVRコンテンツを制作しました。

学園祭に展示するということで、3分程度で説明(チュートリアル)を終え、5分程度のプレイ時間で終わるような内容に設定しています。

また、今回機材にHTC ViveとOculus Rift Sを使えたので、空間を動き回って楽しめるコンテンツにしました。

### 2.1. 草刈りVR
![草刈り.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531621/1c430867-2936-cbb3-48ca-02fc9686de49.png)

辺りに草が多い茂っており、それを右手に持ったカマで**ガシガシ**刈り取ります。
刈り取っても左手のじょうろで水をかけてやればぐんぐん草が育っていくので、育ったらまた**ガシガシ**刈り取ります。

制限時間内にどれだけの量の草を刈り取れるかで競います。刈り取った草の量に応じて途中でステージが変わっていき、どんどんステージがスケールアップしていきます。

体を動かしながらどんどん草を刈り取っていく**爽快感**が特徴です。


### 2.2. 脱出VR
![脱出.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531621/6b562cfa-0095-de6f-c686-39a5dd715c41.png)

ダンジョン風の部屋に閉じ込められ、その中を自由に探索しながら脱出を試みます。
様々なギミックを解いて石版を入手し、正しい位置に配置することでステージを攻略していきます。

なわを**切ったり**、松明を使ってツタを**燃やしたり**、**ジェスチャー**したり....と、トリガーボタン1つで様々な動作が盛り込まれているところが特徴です。


## 3. 使用ツールと機材
### 3.1. Discord
週に2回ほど集まって進捗報告をしたり相談する時間を設けましたが、それ以外のオンラインでのコミュニケーションする場としてDiscordを使いました。

<反省>
様々な相談、会議をしたり、決まったことを共有したり。かなり活発に使われていました。
しかし、活発に使われすぎてチャンネルが無限に増え続けてしまったので、後から見返すものはwiki、テキストでの相談や連絡はSlack、音声通話やチャットはdiscord、といったように用途に分けてツールを使い分けたほうがいいと思います。

複数のツールを使うことによる情報の分散が問題になるようでしたらRedmine + Discord とかもありかもしれません。

### 3.2. Unity & C\# 

VRゲームコンテンツを作るにあたって、ゲームエンジンとしてUnity & C\# を採用しました。

サークルでVR Ready PCを購入することは予算的に難しいです。VR機材はとてもありがたいことに先生方の協力によりお借りする事ができましたが、PCはそういうわけにもいかないので、個人がそれぞれ所有しているPCで開発しました。

その際、(生協で販売されてるような)普通のノートパソコンでも動作するUnityはありがたかったです。

開発中、VRのコントローラー入力とマウス入力を切り替えれるような設計することで、
強めのデスクトップPCを使ってVR部分を開発し、ほかはノートパソコンとマウスで開発が進められるようにできました。

少し具体的に言いますと、開発では「ものをつかむ・はなす」といった動作が実装されているUnityのアセットを使うことになりました。しかし、全員が全員VRデバイスを開発を行うときに持っているわけではありません。そこで、マウス操作でもある程度実装したスクリプトがうまく動くかを確かめられるようにしました。これは脱出VR班の一部メンバーの発案によって組み込まれたシステムで開発序盤中盤でかなり有用に働いたようにおもいます。

### 3.3. Git & Gitbucket , Trello

サークルで借りているサーバーでGitBucketを立ち上げ、プロジェクトをGit管理しました。
これがなかったらグループ開発は全く成り立っていなかったと思います。

タスク管理にはTrelloを使いました。これもグループ全体の把握には不可欠でした。

詳しくは
[大学のサークルでGitbucketとGitを使ってゲームコンテンツをチーム開発をしてみた](https://qiita.com/kimarian/items/d95eda606eae13927145)
へ。

### 3.4. Blender

草刈りVRのカマやじょうろはBlenderを用いてモデリングしました。

VR用ということでポリゴン数やマテリアル数は最小限にし、なるべく負荷をかけないようなモデルを心がけました。

Unityの素晴らしい点の一つは充実したAsset Storeであり、これによりモデリングしなくても3Dゲームを作る事ができますが、自分でモデリング出来るようになると見た目のオリジナリティが出せますし、なにより作れるゲームの幅が広がると思うので、ぜひ無料で始められるBlenderをおすすめします。
(Blender入門の参考にどうぞ : [Blender2.8で超簡単なモデルを作ろう！](https://qiita.com/__DielsAlder__/items/af92bfed925a2d904fba) )

また、今回は
モデル製作 → 修正依頼 → モデル修正
といったサイクルを回して行きたかったため、BlenderファイルもGitでバージョン管理しました。

これについては
[Git Hookにより自動でBlenderのレンダリング・FBXエクスポートを行う](https://qiita.com/inamasu/items/23105e805f039c9ed9df)
に紹介しています。

### 3.5. Hackmd.io

開発中盤で「あれ？ここってどうするんだっけな...」とならないように、開発者全員がゲーム内容を把握できるよう、企画書・仕様書・設計書はしっかり書くよう心がけました。

仕様書は複数人で時間をかけて作成、修正していく必要があったのですが、その際に共同編集が行えるHackmdはかなり便利でした。

Markdownで書け、画像も添付でき、同期のレスポンスも良く、議事録をリアルタイムに共有する際にも使いました。

### 3.6. VR機材(Oculus Rift/Rift S & HTC Vive)

使用機材については、機材をお借りする関係上少々複雑で、

開発初期 : Oculus Rift
開発後半 : Oculus Rift   +  Oculus Rift S ( +時々 HTC Vive)
展示当日 : Oculus Rift S +  HTC Vive

といった感じになりました。

Oculus Rift S は外部センサ無しで、ケーブルも少なく、動ける範囲が広い上に設置の難易度が低くとても良かったです。

開発ではUnityにOpenVRという仕組みがあり、RiftとViveでどちらでも動くアプリケーションがつくれるので利用しました。これがどうやらInputManagerで扱う形式に対応しているようでした。
開発上文字列で入力インターフェースを指定するのはまずい気がしたので列挙体やButtonDown、ButtonUpを取れるように仲介するクラスを一つ用意しました。（参考: [UnityでViveやWindowsMRのモーションコントローラーの入力を統合する方法 - Qiita](https://qiita.com/hadoumune/items/060849776c31ccb1bef3)) 

## 4. 開発の流れ
### 4.1. 企画

夏休み前に学祭でなにか展示しようという話が上がり、話し合いを経てVRコンテンツを２つ展示することに決定しました。

メンバーで集まって、企画についてあーだこーだ考える「企画を練る会」を行い、
固まってきた企画に一人担当者を決めてその人に「企画書」を書いてもらい、検討会の後、コンペを行いました。

誰か一人に企画を考えてもらうのではなく、企画を練る会を開き複数人で企画を考えたことで一人の負担が減り、さらにみんなのモチベーションを高めることができました。
また、みんなで企画を考えることで、開発後半で「あれ？これってほんまに面白いんかな...」という嫌な疑問を抱かずに、「完成さえすれば面白いはず！」という気持ちで開発をすすめることができました。

また、企画書の文章を書くのは一人担当者を決めることで、企画決定までスピーディーに進めることができました。


### 4.2. 学習タスク

1年生や、今回初めてGit・Unityを触る人用に、先輩が学習資料をまとめて、後輩に学習してもらう「学習タスク」を設置しました。
Trelloでタスク化し、進捗が確認できるようにしました。

学習タスクの項目としては、

|項目|説明|
|:--:|:--|
|Unityの学習|シーン遷移、オブジェクトの出現制御(Instantiate)、スクリプト連携(GetComponent)周りを扱えるようにする。
|C#の学習|クラスの定義や基礎的な命令、制御をかけるようにする。|
|Gitの学習|Gitの基本的なコマンドを学習する。fork,pull request,mergeの流れを学ぶ。|
|VRをUnityで扱うための学習|OVRを利用したUnityゲーム開発の環境構築およびスクリプティング方法を解説する文書を作成する。|

といったものを用意しました。

<反省>
gitの学習については、Remoteやプルリクなどの概念の学習や、誤ったコミットを行った際の復旧方法についてもう少し学習が必要でした。メンバーが自分で調べてみたり「ここわかんないんですけど！」とわかってる人に聞くなどその場の機転に助けられた部分が多くあります。
これについては実際に小さなプロジェクト開発をしながら学ぶのが一番だと思うので、学祭前になにか試しに小さなプロジェクト活動をしてみるのが良いと思いました。

### 4.3. 仕様書作成

決定した２つの企画に対して1・2・3年生を割り振り、仕様書の作成を行いました。

今回、きっちり仕様書にまとめるよう心がけましたが、これにより開発中に「あれってどうするんだっけ？」という相談が減り、かなりスムーズに進められたと思います。

また、VR機材をお借りしている先生方に、どんな内容のものをどれくらいの規模感で開発しているかを伝えることができ、意見をもらうこともできたので、きっちり書き上げるようにしてよかったと思います。

### 4.4. 大まかに設計

仕様書をもとに @kimarian と @koske1814 が中心となり設計を行いました。来年度はこのメンバーが参加できるかどうかわからないので大体どんな流れで設計したのかというのを示そうと思います。

流れとしては

1. 機能列挙
2. オブジェクト間で呼び出し合うインターフェースを大体決める
3. クラス構成
4. シーンに存在するオブジェクトの構成

を上から順にやり、その後適宜追加仕様と照らし合わせて修正やクラスの再分割等を行いました。

行った工夫として

- できるだけ分担作業やその場でテストがしやすいようにあるスクリプトが依存するモジュールを減らした
- 依存する場合はできるだけメソッドの呼び方などをわかりやすくした

を意識しました。そのほかにも依存するモジュールをインターフェースとして切り離しておいてそのインターフェースを実装したテスト用のクラスを定義してあげることでテストしやすくしました。

設計序盤まではある程度詳細な部分（メソッド内のデータの扱い方）等も書いていましたが、コア部分が終わった後はフィールドやメソッドはpublicなもののみ指定し、それらの大体の機能を書くというスタンスにしました。

設計書がなければ「ここのこんなモジュールでこんな風にいい感じにしてー」という風に口頭で説明したり、チャットツールで情報が分散して存在する状態になってしまいます。そうすると説明の齟齬があったり実装上の不明点が発生したときにほしい情報をとってくることが難しくなります。そういう点を考えると設計書をきちんと容易したのは正解だったと思います。

### 4.4. 開発

大体の開発では「設計書に記載した1クラスを実装してきてね」、「このリソース用意してね」「このシーン構成してね」といった形態でTrelloでタスクを発行しGitbucketからGitコマンドで対応リポジトリをクローン or プルして作業、出来上がったらプルリクエストという形態をとっていました。
前半は画像等のリソースもリポジトリに含んでいましたが、リソース等に関しては後半、UnityPackageに切り離して扱う等の工夫をしていました。

Gitbucket等の運用については [大学のサークルでGitbucketとGitを使ってゲームコンテンツをチーム開発をしてみた](https://qiita.com/kimarian/items/d95eda606eae13927145) を参照していただけるとうれしいです。

両班大体同じような段階を踏んで開発が行われていて

1. 設計書をもとに各クラスを実装する(ここは大体設計者はあまりコードには触れない)
2. 各クラス・モジュールが出来上がってきたら設計者やコード全体を見渡している人が結合する
3. 大体できたコンテンツを仕様の中心的な策定者が設計者と相談しながら調整する

という風になっていました。

@kimarian 的に成功だったのは3の仕様を決めた人がゲーム調整を行うという部分です。特に草刈りゲームに関してはスコアの伸び方について慎重にちゃんとした基準をもって調整するのはゲーム体験上非常に重要だったと思います。

しかし同時に改善の余地ありと思ったことがあります。ゲームバランスを制御するパラメータが散在していた点です。「あのパラメータ調整したいんだけどどのオブジェクトのどのパラメータかえたらいいんだ？」という意見が多く上がっておりゲームバランス調整作業が結構煩雑でした。設計の話に戻ってしまいますが、今回の開発の場合、ゲームバランスに関わるパラメータは局所的にまとめて調整できる機能を組み込む等の工夫を施すべきでした。

### 4.5. 運営

学祭当日はVRコンテンツを２つと、小さな子どもさん向けにEye Trackerを用いた体験コンテンツを展示しました。

VR一つに 4m × 5m 程度の空間を設けて自由に動き回ってもらいました。HMDのケーブル持ち係を設けて、体験者がケーブルに引っかからないように気をつけました。

小学生以下の子供さんにはVRを体験してもらえないので、そういった方々向けにVR以外の展示物を用意したのは正解だったと思います。

<反省>
自由に動き回れるようにしたせいで、ケーブル持ち係の負担がかなり大きくなってしまいました。
また、体験者がくるくるその場で回転してしまうことも多く、ケーブルがねじれて痛みそうになってしまいました。

商業施設であればケーブルを上から吊るすこともできるでしょうが、学祭は教室を借りているだけなのでなかなかそういうわけにもいきません。
ケーブルのことも考慮したゲームデザインにする必要がありそうです。

あるいは、Oculus Questを採用するとか。(スペック的にかなりの最適化が必要そうではあります)

## 5. 来年に向けて

最後に、来年に向けての反省や改善点をあげていこうと思います。
個々の小さな反省点についてはこれまでに書いたので、全体的な改善方針について書いていきます。

### 5.1. 勉強会の整備

Unity、C\#、Gitなどに全く触れたことがない人が開発に参加するには学ばなければならないことも多く、負荷が大きくなってしまいました。

そこで、学祭プロジェクト前に勉強会やプロジェクト開発の機会を設けるべきだと思いました。

GitやUnity、C#の勉強会を開き、さらに実際にGitを用いて少人数でプロジェクト開発をすると良いと思います。

2日~二週間程度でハッカソン的なのを開いてみるとかも面白そうです。

### 5.2. 開発フロー見直し

今回、「企画→仕様決定→設計→プロトタイプ→開発→テスト→リリース」

といったウォーターフォール型的開発になりましたが、これは開発期間が開発規模・リソースに対して短かったために、こうせざるを得なかった、というのが正直なところです。

より良いゲーム開発のためには、スパイラルモデルといった他の開発手法も検討すべきだと思います。

そのためにも、勉強会などの整備をして、開発期間をより効率良く使えるようにしたいです。

### 5.3. 技術的な調査を先行して行う

草刈りVRに関して開発中盤まで「これパフォーマンス的に大丈夫か・・・？」という大きな不安がありました。ある程度動くようになって不安は消え去りましたが、これはあんまりリーダーや設計者的には結構な重圧でした。

今後の開発ではそのコンテンツでどのような技術をつかうか？をきちんと分析し技術的な知見のある人が検証作業を行うべきだと考えます。