Unity + Epic Online Services でオンラインゲームを作ろう ～①チャット編～

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> + <a href="https://twitter.com/hashtag/EpicOnlineServices?src=hash&amp;ref_src=twsrc%5Etfw">#EpicOnlineServices</a> でチャット <a href="https://t.co/eaEhziiFoM">pic.twitter.com/eaEhziiFoM</a></p>&mdash; オカ (@okagamedev) <a href="https://twitter.com/okagamedev/status/1282329275467591680?ref_src=twsrc%5Etfw">July 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

今年5月に Epic Games から Unreal Engine 5 が大々的に発表されましたが、
同時に [Epic Online Services](https://dev.epicgames.com/ja/services?lang=ja) (以下 EOS)という
リアルタイム通信対戦ゲームを開発するためのプラットフォームも発表されました。
この分野は Photon と Monobit が有名です。

なんと競合製品の Unity にも対応という謳い文句です。

ですが、まだまだサービスが開始されたばかりで公式以外に全く情報がありません。
C# の公式デモはありますが、 Unity のデモはありません。
ユーザーが増えて開発が活発になることを願って、Unity のデモを作成しました。

## 既知の問題

先に重大な問題を書いておきますと、 7/12 現在 **ロビー検索が動きません**
ロビー検索ができないと、通信相手と同じロビーに入室することができず、P2P 通信を始められません。
公式のバグレポートや[フォーラムのスレッド](https://eoshelp.epicgames.com/s/question/0D52L00004XsLS2SAN/update-unity-lobbysearchfind-result-is-unrecognizedresponse)で報告はしておりますが、なかなか修正してもらえません。

暫定対処として、ロビー作成時に発行されるロビーIDをクライアント間でどうにか共有することで、ロビーに入室しています。
このままでは Firebase などの外部サービスを立て、ロビー検索を自前で作るしかありません。
公式には早急に直していただきたいところです。

## 筆者環境
OS: Windows 10 Pro
Unity:Unity 2019.4.3f1
## 利用ライブラリ
* [UniTask](https://github.com/Cysharp/UniTask)
* Epic Online Services C# SDK Ver 1.7.0

## デモ
下記の Github リポジトリに配置しました。
https://github.com/okamototomoyuki/unity_eos_chat

Unity + EOS で作ったチャットになります。
~~ゲームじゃないじゃん~~　ゲームに必要な機能の確認レベルです。
通信部分は P2P で実装しておりますので、
通信データをメッセージから、キャラ座標などの情報に置き換えてゲームに組み込んでいただければです。

## デモを動かす

### Epic Games のアカウントを2つ作成
EOS のユーザー情報には Epic Games のアカウントを使います。
メールアドレスを２つ用意してアカウントを作成してください。
https://www.epicgames.com

### EOS のクレデンシャル作成
デモを動かすためにはご自身で EOS のクレデンシャルを作成していただく必要があります。
Epic Games Japan が日本語の解説動画を上げてくれております。
12:15～23:30 がクレデンシャル作成の解説です。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">先日公開されたEpic Online Services (EOS)の概要、及び実際にSDKをダウンロードしてサンプルを動かす手順を説明します<br>EOSはどのエンジンにも、どのストアにも、どのプラットフォームにも対応していますので、UE4ユーザ以外の方にもおすすめです<a href="https://t.co/v9nOPVIBlm">https://t.co/v9nOPVIBlm</a> <a href="https://twitter.com/hashtag/EGJ%E3%82%AA%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0?src=hash&amp;ref_src=twsrc%5Etfw">#EGJオンラインラーニング</a></p>&mdash; アンリアルエンジン (@UnrealEngineJP) <a href="https://twitter.com/UnrealEngineJP/status/1265877382621085696?ref_src=twsrc%5Etfw">May 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### Unity で EXE 作成
* **Assets/ScriptableObjects/EOSSettings** に作成したクレデンシャル情報を入力
* Windows Standalone でビルド

### EOS DevAuthTool を起動
ゲーム上でユーザーが EOS にログインするとき、通常はブラウザが起動してIDとパスワードを入力します。

しかし、開発中にこのログイン方法のままでは、テストのたびにテストユーザーの数だけ
「ブラウザ起動」⇒「ログイン」⇒「ログアウト」⇒「ブラウザ起動」⇒「別のユーザーでログイン」⇒…
となり、とても面倒です。

この面倒を解決してくれるのが SDK に同梱されている **EOS DevAuthTool** というツールです。
テストするユーザーをログイン状態に保持してくれます。

Assets/ExternalAsset/EOS-SDK-CSharp-13812567-1.7/SDK/Tools/EOS_DevAuthTool-win32-x64-1.0.1
を解凍して中身の EOS_DevAuthTool.exe を実行してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/a482e086-9470-6828-fccf-363871bccd18.png)
ポート番号の入力が求められます。
本デモでは **8765** をデフォルトにしてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/cfcc42e7-4645-efb6-a988-863ca62b09d6.png)
アカウントをログインさせるページが表示されました。
先に作成した Epic Games のアカウントを２つログインさせます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/586bbabe-1986-dafe-30d8-53fb25b0ef05.png)
credential name は適当な名前を入力してください。
この名前はゲーム側で使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/6d2cabbe-2138-8afc-b12f-1832987c7468.png)
二人分のログインが完了しました。
ツールは起動したままにしてください。

### デモ実行
EXE を２つ起動します。

#### ログイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/f232bc6c-9ad9-8e78-3952-d724b9c38827.png)
それぞれ **Dev User Name** に先ほど EOS DevAuthTool で入力した credential name を入力し、Login を押してください。

#### ロビーの作成と入室
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/4392423c-3b95-9500-88e8-9ba334f9c919.png)
1. 左側で **Create Lobby** を押す
　しばらくすると画面が切り替わり **Lobby Id** 欄にランダムな文字列が生成されます。
　また、この時点で左側はロビーにログインしています。
2. 生成された文字列をコピー
3. 右側の Lobby Id 欄にペースト
4. 右側で **Join Lobby** を押す
両方ともに **Chat** と書かれたエリアが表示されたロビー入室完了です。

#### チャットで通信
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/522476b3-2aa3-9966-3d4e-02086b38e12e.png)
メッセージを入力して **Send** ボタンを押してみましょう
もう片方の **Receive** 欄に表示されるはずです。
P2P 通信成功です。

## 細かな問題

### Editor で破棄処理が機能してない
https://dev.epicgames.com/docs/services/ja/CSharp/GettingStarted/index.html
上記 C# の解説ページの「SDK を初期化してクリーンアップする」の章に
完了時に破棄処理を呼ぶようにとありますが、現在(Ver1.7) Unity Editor で機能しません。
Unity Editor を消さずに２回初期化(PlatformInterface.Initialize) を呼び出すと「Result.AlreadyConfigured」エラーになります。
このままでは ゲームを実行するたびに Unity Editor 自体を再起動しなければいけません。

https://eoshelp.epicgames.com/s/question/0D52L00004Ss2leSAB/platform-initialization-fails-from-2nd-time-on-unless-i-restart-unity
公式の回答でUnity Editor の場合は下記で回避するように、となりました。
・Result.AlreadyConfigured は無視
・破棄処理(PlatformInterface.Shutdown)呼ばない

## まとめ
重大なバグが放置されてるため、まだまだ本格利用は難しいですが、

- 無料
- サーバー不要
- ソーシャル機能
- (予定)ストア機能

と成熟すればかなり魅力的なサービスになると期待してます。
よければ皆さんも情報共有どんどんして、サービスを盛り上げていきましょう。