しがないエンジニアのブログ

技術的な内容をメモ代わりにつらつら

[Unite2019] Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~

動画・スライド:https://learning.unity3d.jp/3341/

小端 みより 株式会社ミクシィ


学んだ知見

Unityサーバを利用することで、
クライアントエンジニアでもサーバ構築が可能

  • c#で実装できる
  • Unity機能が使える(Animation, Physics, AIなど)
    • プロファイラが使える!!
  • 単一プロジェクトで管理

サーバ処理型で実装できる

  • チート耐性が高い
  • 通信が安定する
  • クライアントの処理負荷を軽減できる

講演概要

Unityサーバを作にあたって

これまでのマルチプレイ実装
P2P型(クライアント処理型)

  • メリット
  • デメリット
    • チートされやすい
    • 通信が不安定になりやすい
    • 大規模タイトルに向かない

→ サーバ処理型にすればいいのでは?

Unityサーバとは

  • Unityで作る専用サーバ
  • c#で実装できる
  • Unity機能が使える(Animation, Physics, AIなど)
  • クライアント、サーバ両方を単一プロジェクトで管理

作成するゲームの概要

7つの課題と解決法

1. どの通信ライブラリを使えばいい?

  • 公式
    • Unity Transport Package
    • DOTS
  • 非公式
    • LiteNetLib

ゲーム設計によってどういう実装をすればいいかのフローチャートも参考に
https://blogs.unity3d.com/2019/06/13/navigating-unitys-multiplayer-netcode-transition/

結論:
LiteNetLibを採用
API実装がある程度かたまっている

2. TCPUDPどっちを使う?

初めて使うならTCP

  • ポピュラーで情報が多い
  • プロトコルとして信頼性が高い

しかし、リアルタイム性という点においてTCPの再送制御は致命的

結論:UDPを採用

3. 再送制御による遅延を回避するには?

UDPを使う
UDPで信頼性を得るには…

送信メッセージを冗長化

結論:UDP + 冗長化で対応

4. MTUって何?

Maximum Transmission Unit

  • 1回の通信で転送可能なデータグラムの上限サイズ
  • 超過した場合は分割される or そもそも到達しない

対処法

  • メッセージサイズを削減する
    • プレイヤー視界外のオブジェクトをカリング
    • オブジェクトの距離、優先度に応じて通信タイミングを分散させる
    • データを圧縮
  • デルタ圧縮
    • 送信内容をキャッシュする
    • 更新されたオブジェクト、プロパティのみを送信

結論:上記のテクニックでメッセージサイズを削減

5. ラグはなくせるのか?

一般的にラグ = 通信遅延と思われているが非常に小さい(1, 2ms)
実際は再送制御の遅延、通信サイクルに起因するもののほうが大きい

入力のアップデートのタイミングが悪いと必ず起こる宿命
→ 体感上のラグを打ち消す

例)

結論:
オンラインゲームにおいてラグは宿命
体感上のラグを減らす工夫をする

6. サーバとクライアントで同一プロジェクト管理できる?

ビルド設定で使用するアセットを切り替えればよい
クライアント・サーバのどちらで必要なアセットかを区別する

結論:
シーン/アセットをどちらで使うかビルド時に判別・切り替え
→ AssemblyDefinitionを利用

7. 専用サーバをどうやって運用したらいい?

ホスティングサービスの利用

結論:GameLiftを採用


所感

  • Unityでサーバ構築をできることを知らなかったのでとても参考になった
  • 結局サーバ構成を考える部分が生じるのでサーバエンジニアは必要そう
  • 1日目の講演であったGame Server Services(GS2)と両立できるのかが気になった