ゲームが作りたい！！オンラインゲームの作り方全体像

**初投稿です。**
しきたりとか分からないので、「なんかお前やばいぞ」って思ったら教えてください。

ゲームの制作手順をおおまかに全部書いていくのですが、特に自分がオンラインゲームを作り始めるにあたって「この情報があればもっと楽に進められてた」って思うことを交えて進めていこうと思います。

「ゲーム作りたいけどそもそもどうやって作るもんなの」みたいな方の参考になればいいかな、と。

追記(2021/3/31)
Unityの操作に慣れてきたのでさらにいくつかの実戦的な知識を追加しました
想定読者は

「ゲーム作りたいんだけど何勉強したらできるん？」
「ゲーム開発って何すればいいん？」

って人から

「オンラインゲームを実装したいけどどういう方式があるのか分からない」
「FPSのオンラインゲームを作りたい、RPGのオンラインゲームを作りたい、けど通信ってどうするん？」
(ここら辺のひとは最後の方を見てね)

という人までです。


#本日のメニュー
- ゲームエンジン(ゲーム制作ツール)について
    - Unityについて
    - 実際の制作作業について
- プログラミング言語について
- Unityでのオンラインゲームの選択肢について
- HTTP通信について
    - サーバーとwebアプリケーションについて
    - HTTP通信の内容について
    - GETとPOST
  

#ゲームエンジンについて
簡単に言えばゲームはゲームエンジン(ライブラリとも言う)というソフトで作られます。
例えば有名なゲームエンジンにUnity(ユニティ)がありますが、スマホやPCゲームの起動画面にロゴを見たことある人が多いのではないでしょうか。

例えばスマホゲームのWarRobotsやCriticalOps、最近では任天堂のスマホゲームにもUnityが使われています。
ゲームエンジンはUnityだけではなく、他にもcocos2d-xやSourceEngine、OpenGL、FoxEngine、Unreal Engineなどがあります。



じゃあどれを使ったらいいんだこの野郎、とお思いかもしれませんがそれは個人の相性だとか、エンジンの得意分野によって決めればいいと思います。

おすすめなのはUnityです。母数が多く参考書も多く、利用料がよほどの規模にならない限り無料だし、多くのプラットフォームに対応してるのが主な理由となっています。ちょっと試すならUnity一択だと思います。

もう一つの候補であるUnreal EngineはUnityに比べて綺麗なグラフィックを簡単に作ることができます。しかし日本語の情報が少なかったり欠点があり、熟練者向けとされています。まぁここは「ゲームエンジン　どれがいい」とか「ゲームエンジン　神」とかで適当に検索してください。

###実際どんな作業なの？
自分はUnityしか使ってませんが、ゲーム制作といってもかなりビジュアルに特化しており、直感的にオブジェクトを配置したあとプログラムで具体的にどんなことをやるかのか決める感じです。なんならプログラミングしなくても、買ったアセット(ゲーム制作の素材のようなもの)をてきとうに配置するだけで初心者でもゲームを作れてしまいます(「え！？」と思ったそこの君、今すぐUnityをインストールすれば明日にはもうゲームが完成するぞ！)

ほかにも元から物理法則や衝突判定などゲーム制作を支援する機能がたくさんついているので、それらの機能を使えばゲーム開発と言ってもあんまりやることがありません。ゲームのルールを決めるぐらいです。
興味を持ったら「Unity やり方」とかでてきとうにググってください。

#プログラミング言語について
さてゲームエンジンを決めたら次はプログラミング言語を決める、と思うかもしれませんが実はエンジンによって使える言語は限られています。

つまりゲームエンジンを決めたらおのずと言語まで決まっちゃうんですよね(たいてい１か２種類)。
自分のほかの専門分野の言語と相談してエンジンを決めてもいいかもしれません。

# Unityでのオンライン実装について
さぁこっからが本題です。
自分が分からなかったころの検索結果を見る限り「Unityでのオンラインゲームの作り方」はおそらく多くのユーザーが挫折しています、というかおそらく出発点にすら到達できていません(検索結果でそういう類の質問と、ぼんやりした答えを多く見てきたため)。

まぁおそらくですが一番の落とし穴は公式ドキュメントですね。
実はあのドキュメントかなり情報が未整備の状態です、というのも完全に開発者のメモみたいなものであって良い説明ではないんですよね。
ここからはそれもふまえてオンライン実装の選択肢について自分が調べた限りでお伝えします。

###オンライン実装の選択肢
- UNETを用いる方法
- Photonを用いる方法
- ニフティクラウドモバイルバックエンドを用いる方法
- サーバーを用意する方法

だいたい調べた感じだとこれらが主な選択肢です。
しかし「UNETを用いる方法」は2018年に廃止され、現在は前まで使っていた開発者に対するサポート期間となっています。(入れようと思えば入れられるが公式は非推奨)

**にも関わらず、公式ドキュメントの9割はこのUNETについて書かれています**
これが一番の落とし穴たる要因ですね。わけもわからず「NetworkManager」の項をひたすら読み続けた方もいるのではないでしょうか(僕です)。
実質正攻法ではマルチプレイにたどり着けないっていうわけですね。

###Photon、ニフティを用いる方法　
これはオンラインゲームを実装しやすくする外部パッケージを導入する方法です。

オンラインが実装しやすい分制約が多く、どうしても自由度が低くなってしまいます。

手軽に実装したい！とりあえず動けばいい！という人ならこれが正解だと思います
書籍もあり、導入方法について書かれたサイトも多いので詳しい説明はてきとうにぐぐってください。

###サーバーを用いる方法
自分でサーバーサイドの処理を詳しく書いて通信をする場合です。
とはいってもそんなに難しい話ではなく、Unityでサーバーに送信したデータをサーバーで加工、保存してUnityに返すのがおおまかな流れになります。

サーバーにはサーバーソフトウェアとwebアプリケーションが必要になります。
「え？ゲームなのにwebアプリケーション？」と思うかもしれませんけどもHTTP通信を行う、という意味でwebアプリケーションが必要になります。
このwebアプリケーションが実際の処理、サーバーソフトウェアはコンピューターをインターネットにつなぐのために働きます。

つまりこの実装を行う場合はwebアプリケーションを使う知識が必要になります。
(イメージ)
![IMG_0461.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496596/d0574db8-966f-7439-3827-177c3161c23a.jpeg)

webアプリケーションも自分が好きなものを選べばいいと思います。
一番無難なのは母数が多いRuby on Railsです。
それでも海外ではかなり多くの開発者がいるので英語が読めればどのフレームワークでも不自由はないと思います。

以下の内容はwebアプリケーションをやってれば必ずどこかで知る基礎知識なので「なんだ、もう俺の悩みは解決したわ」っていう人はwebアプリケーションについて勉強し始めるのが良いんじゃないでしょうか。

###HTTP通信の内容について
HTTP通信というとなんだか難しい気がしますが、「こういうルールで通信しようね」っていう決まりみたいなものです。
なのでルールにのっとった書き方を覚えれば難しいことはありません。

簡単に言うとHTTP通信はこのルールにのっとって書いたテキストを相手側にぶん投げるってかんじです。
つまりデータを書く作業、ぶん投げる作業、受け取って取り出す作業が必要になるわけですね。

その肝心のデータの内容は、通信の状態(ブラウザの設定とか端末情報とかどうでもいいやつ)とステータスコード(通信の成功、失敗の理由)と通信の本体(body)に分けられます。
大抵の場合このbodyに値を書いて、webアプリケーションやUnity内で取り出す形になります。

###GETとPOSTについて
まぁこれもどっかで聞いたことがある方が多いのではないでしょうか。
これはクライアント(Unity)側でサーバーに通信をするときに使われる方法の種類です

- GET　データなしでサーバーにリクエスト(通信の要求)をします
- POST　データありでサーバーにリクエストをします

なんだこれ、と思いますがけっこう簡単な話です。
例えばゲームの部屋情報の一覧を得るときはデータを送る必要はありませんね。サーバー内にある部屋のデータだけ受け取ればいいので、こういう場合はGETでリクエストをします。

しかし銃を撃つ、モンスターを召喚する、アイテムを使う場合はこうはいきません。なぜなら「どんな銃をどこに向けて撃ったか」、「どんなモンスターを召喚したか」、「何のアイテムを使ったか」をサーバー側で知る必要があります。この場合はPOSTでこれらの情報を付けてリクエストする必要があります。

サーバー(webアプリケーション)内ではGETかPOSTか、どんなデータがついてるか、を判断して異なる処理をするように記述します。

##さらなる選択肢( 注意：上級者向け )
ここは初心者の方は読み飛ばしてスペック要件をよく読み、とっととUnityをインストールしましょう。スペック的に動かなそうならお母さんに「俺な、個人ゲーム開発者目指しててん。」と言ってBTOでゲーミングPCでも買ってもらいましょう。

さて、ここからは「またこの記事もハズレか」と流し読みしていたお兄さん達とお話をしましょう。
まず上の選択肢のメリットデメリットをまとめます。単語は後で説明するので分からなかったらまずは飛ばしてください。

| 選択肢 | 利点 | 欠点 | 難易度 |
|:-:|:-:|:-:|:-:|
| UNET | オワ |  コン |  |
| Photon  | 実装最速、最初からUDPでソケット通信、リアルタイムゲームに強い  |  維持費がそこそこ | 簡単
| webアプリ(HTTP) | プログラマースキルが上がる、データベースが使える | リアルタイムは不可、ゲームの種類によっては向かない | 普通
| webアプリ(WebSocket) | リアルタイムにできる | 個人でwebsocketは希少種 | きつい |
| Unityのサーバー | サーバー・クライアントでロジック共有できる |  | 普通 |

UNETはこんなこと書いたら怒られるかもしれませんが2021年3月現在終わってます。

Photonやニフティの維持費は難しいです。500CCU(同時接続数)で1万7000ですね。回収できる自信がある方はどうぞという感じなのですが、ちょっと勇気要りますよね。大手企業も導入していて無料プランもあるので、お試しでやってもいいかもしれません。
UDPやソケット通信はプログラマーとしては中級者以上向けの技術なので、それがお手軽に実装できるのは大きいです。リアルタイムゲームに強いとはこのソケット通信とUDPの恩恵です。もしPhotonを使わずにオンラインFPSを作りたい場合は自分でUDPとソケット通信を組む必要があります。

webアプリは完全に自分でカスタマイズできます。Photonはおそらく、接続したプレイヤーを一緒の部屋に入れるみたいな機能しかないような気がする(偏見です。間違ってたらご指摘を)のですが、Webアプリならばプレイヤーのデータをデータベースに保管するのである程度チート対策ができ、自分の好きな時に好きな量の通信ができます。
まぁ要はソシャゲなどを作る場合はこれ、で買い切り式のオンラインゲームなどはPhotonがいいのかな？そこらへんPhotonのアプリ内課金はどうなってるんでしょうね。分かりません(笑)

webアプリ(websocket)はwebアプリにwebソケットという機能を追加したものです。そもそもこれにはHTTP通信の一個下のソケット通信の仕組みを理解する必要があります。Linuxのファイルディスクリプタで練習してみるのが一番手っ取り早くその挙動を理解できると思いますが、まぁここらへんの単語(「ソケット通信　仕組み」とか)をぐぐって頑張って理解してください。要はwebsocket通信はリアルタイムかつ従来のソケット通信よりも効率が良くなったものです。
ただし、処理はwebアプリ内で記述するのでリアルタイムと言ってもFPSの弾道計算とかは厳しいと思います。カードゲームやアクションじゃない2Dゲームならこれで実装できると思います。

UnityのサーバーはUnity内にソケット通信の処理を記述し、サーバー向けにビルドしてUnityでサーバーサイドを作っちゃう方法です。先駆者がいるので適当に「Unity ソケット通信 サーバー」とかで検索してください。
ここは試したことがないのでLinux向けにビルドして動くのかとか気になります。

あと例外的にサーバーのコンソールアプリで言語のライブラリのみでソケット通信を実装して作る方法もあると思います。作ったらすごいです。


#終わり
まぁざっとこんな感じです。
あの時右も左も分からなった自分が読んで納得できるように書いたつもりです。

webアプリケーションは書籍がかなり多いので、そちらを流し読み(webページやフォームなど直接関係ないものが多いので)して公式ドキュメントで全体を見る感じでいいと思います。

サーバーPCについては自宅とレンタルやVPSという選択肢がありますが、それらについてはかなり分かりやすい記事があるのでそちらに任せます。
簡単に言うと判断基準はDNSの名前解決の登録料、パーツの消耗、IPの固定料金とかが絡んできます。

Unity側のGET、POSTについてはQiita内に分かりやすい記事が２つほど、[スクリプトリファレンス](https://docs.unity3d.com/Manual/UnityWebRequest-HLAPI.html)に旧型(WWWFormを用いる方法)と新型(IMultipartFormSectionを用いる方法)について詳しく書いてあります。

VPSの利用は[さくらVPSの説明ページ](https://knowledge.sakura.ad.jp/7938/?_gl=1*13jt1yk*_gcl_aw*R0NMLjE1NzE3NDY2NDQuQ2owS0NRancwYnJ0QlJET0FSSXNBTk1EeWticEVVcHBXRll6c01QYXNuQUZORm1zNDFUWkRjTTlka3JlZ0J4WEo1Y1gyZ1FsOUo5UnlqWWFBdjAtRUFMd193Y0I.&_ga=2.33018302.1652084493.1572582557-614517120.1561300356&_gac=1.222237162.1571746660.Cj0KCQjw0brtBRDOARIsANMDykbpEUppWFYzsMPasnAFNFms41TZDcM9dkregBxXJ5cX2gQl9J9RyjYaAv0-EALw_wcB)がかなり分かりやすいのでそちらを見るのをおすすめします。

あとUnityのマニュアルはやばいので読まない方がいいと思います。とりあえずやり方をググったら具体的に出てきたクラス、関数をスクリプトリファレンスで確認する程度が普通かと。まぁ正直スクリプトリファレンスも読まないです。「Unity (やりたいこと)」で検索すれば大抵先駆者がいるので、Unityの動作の仕組みとC#が分かっていれば「こう書けばいいんだな」ってのも分かります。

あとはUDP、Websocketについては必要に応じてググってみてください。