Fusion専用サーバー
概要
Fusion 専用サーバーサンプル では、専用ゲームサーバー
というコンセプトで Fusion プロジェクトを構築し、ゲームサーバーとして動作するヘッドレスインスタンスを構築する方法を紹介します。
専用サーバーとは、サーバーモードで起動された Fusion ピアのことで、ローカルのプレイヤーは存在せず、ゲーム状態全体を管理する State Authortity
として動作します。
このサンプルでは、インスタンスがヘッドレスモードで動作しているかどうかを検出し、自動的に Server Mode
で起動できるようにしています。また、クライアントとして起動してランダムな Game Session
に参加するか、Lobby
に参加して特定の Session
を選択できるシンプルなメニューも用意しています。
始める前に
サンプルを実行するには、まずPhotonEngine Dashboard で Fusion AppId を作成し、リアルタイム設定 (Fusion メニュー) の App Id Fusion
フィールドにペーストしてください。
ダウンロード
バージョン | リリース日 | ダウンロード | ||
---|---|---|---|---|
1.1.6 | Jun 02, 2023 | Fusion Dedicated Server 1.1.6 Build 194 |
プレハブ
Server_NetworkRunner.prefab
: サーバが使用するNetworkRunner
プレハブ。ゲーム全体を管理するスクリプトが含まれており、主なものは以下で説明するGameManager
です。Server_Manager.prefab
: 現在のゲームインスタンスが Headless Mode で動作しているかどうかを確認し、Server_NetworkRunner.prefab
を生成します、また Fusion Server をカスタマイズするために必要な引数も取得します。Client_NetworkRunner.prefab
: クライアントが使用するNetworkRunner
プレハブです。プレイヤーからのInputを取得する役割も担っています。Client_Manager.prefab
: クライアントが特定のセッションやランダムなセッションに参加したり、ロビーに参加して利用可能なセッションを確認したりするためのシンプルなGUIを作成します。Client_NetworkRunner.prefab
を利用します。Player.prefab
: クライアントがゲームに参加したときにサーバから生成されるシンプルなプレイヤーです。
シーン
0.Launch
: 起動シーンはServer_Manager.prefab
インスタンスを保持し、Headless Mode で動作している時にサーバーがGame
シーンを読み込むための開始点として使用されるか、通常のシナリオではMenu
シーンのみを読み込みます。1.Menu
: このシーンはクライアントインスタンスによってのみ使用され、Client_Manager.prefab
によって構築されたシンプルなメニューが表示されます。2.Game
: 基本的なゲームシーンで、プレイヤーはスポーンされ、動き回ることができます。
スクリプト
SceneDefs
: 参照しやすいように、インデックスごとにシーンリストを保持しています。CommandLineUtils
: インスタンスが Headless Mode (コマンドラインに-batchmode -nographics
を含む) で動作しているかどうかを確認し、コマンドラインから渡された引数から値を取得するメソッドのセットです。ServerManager
:CommandLineUtils
を利用してGame Server
を起動するかMenu
シーンを読み込むかを選択できるようにしました。-session
: サーバーが使用するカスタムセッション名。-region
: サーバーが接続する必要のあるカスタムリージョン。対応するリージョン](~~~/connection-and-authentication/regions) のリストです。-lobby
: セッションが作成されるカスタムロビー。-port
: サーバーが起動時にバインドしようとするカスタムポート。-P
: カスタムプロパティのセットです。
GameManager
: サーバー上で動作し、基本的に参加/離脱時にプレイヤーをスポーン/デスポーンします。ServerEventsInfo
: Fusionのサーバー側で発生する最も一般的なイベントのログを取得します。ClientManager
: クライアントメニューをコントロールし、ゲームサーバに接続するためにClient_NetworkRunner.prefab
を使用します。PlayerController
: クライアントからの入力を読み、Player NetworkObject
を動かすシンプルなコントローラです。InGameMenu
:Game
シーンでクライアントとして動作しているときに、Shutdownボタンを表示します。
実行方法
サンプルを実行するには、Scene in Build
で 3 つのシーンが正しい順番で並んでいることを確認し てください(Launch, Menu, Game)。
これにより、アプリケーションはコマンドライン引数をチェックし、サーバーまたはクライアントを起動することができます。
各モードの起動方法は、以下の通りです。
専用サーバーモード
このモードでは、デフォルトの設定や起動時に渡されるカスタム引数を使用して Game Server
が起動されます。サーバーはディスプレイやビジュアルを使用せずに実行されることを考慮し、いくつかの必須引数といくつかの任意引数があります。
ゲームサーバー
は主に2つのビルドターゲットを使用してビルドすることができます。
スタンドアロンビルド
: 主要なプラットフォーム(Windows, Linux, macOS)用の実行ファイルをビルドするために使用される、通常のビルドターゲットです。この場合、いくつかのデメリットがあります:(i)ビルドには全てのゲームアセットが含まれ、(ii)一度実行するとバックグラウンドで実行されます(強制終了するにはプロセスを終了させる必要があります)。専用サーバビルド
: このビルドターゲットはUnity 2021.2+でのみ見つけることができ、この目的のために特別に設計され、不要なファイルを削除し、ターミナルとの統合がより良くなっています。このビルドターゲットの詳細については、[こちら](https://forum.unity.com/threads/unity-2021-2-dedicated-server-target-and-stripping-optimizations-now-live-please-share-feedback.1143734/) を参照してください。
ビルドがあるフォルダを起点に、ターミナルコンソールを開き、次のように入力します。
.\FusionDedicatedServerSample.exe -batchmode -nographics -logFile output.log
これだけで、Game Server
を実行し、新しいGame Session
を作成し、すべてのデフォルト設定を使用してホスティングマシンの場所に基づいてBest Regionでパブリッシュすることができます。
引数を分解してみましょう。
batchmode -nographics
(mandatory): Unity インスタンスを Headless Mode で実行します。これはゲームサーバー
の起動をトリガーするものです。-logFile output.log
( 任意 ): これはoutput.log
という名前のファイルを、サーバーからのすべてのログと同じフォルダに作成します。
上記の引数はすべてUnityに関連するもので、より詳しい情報はこちらを参照してください。
前述の通り、ゲームサーバー
は追加の引数をパースすることができます。
.\FusionDedicatedServerSample.exe -batchmode -nographics -logFile output.log -session my-custom-session -region us -lobby my-custom-lobby -port 30001 -Pmap city -Ptype free-for-all
上記の呼び出しで、ゲームサーバー
は以下のことを行います:
-session <custom session name>
( 任意 ): my-custom-session という名前でGame Session
を開始します。デフォルトはランダムな GUID です。-region <region ID>
( 任意 ): リージョン US に接続します。デフォルトは Best Region です。-lobby <custom lobby name>
( 任意 ):ゲームセッション
を my-custom-lobby という名前のLobby
に公開します。デフォルトは ClientServer ロビーです。-port <custom port number>
( 任意 ): ポート 30001 にバインドします。デフォルトは27015
です。-P<property name> <value>
( 任意 ): カスタムプロパティ map = city と type = free-for-all を設定します。デフォルトは空リストです。
上記の引数はいずれも必須ではなく、単独で使用することも、特定のサブセットを混ぜて使用することも可能です。
一度起動すると、ゲームサーバー
はクライアントの参加を待ち、すべてのクライアントがセッションから切断すると自動的にシャットダウンして終了します。
API
サーバーモードで Photon Fusion を実行するのは非常に簡単ですが、サーバーを実行するホスティングマシンのネットワーク特性によっては、別の設定が必要になる場合があります。
そのため、以下に GameMode.Server
で Fusion を起動するための主な方法を3つ示します。
- 完全自動:ピアは起動し、OSがソケットレイヤーに与える利用可能なポートにバインドします。これは、事前に定義されたポートを必要としないほとんどのシナリオで機能します。STUNプロトコルは、ピアのPublic EndPoint (
IP:Port
) を解決するために使用されます。これは、国内のインターネット接続のように、デフォルトでポートをブロックしないほとんどの一般的なネットワークに適しています。
C#
NetworkRunner.StartGame(new StartGameArgs() {
GameMode = GameMode.Server
// other args
});
- 事前定義されたローカルエンドポイントと自動パブリックエンドポイント:ケース1に似ていますが、ここでは特定のローカルエンドポイントがサーバーで使用されるように設定されています。同じポートに他のサービスがバインドされている場合、ピアの起動に失敗するため、それが利用可能であることを確認します。この例では、サーバー は エンドポイント
192.168.0.10:27015
にバインドしようとしますが、これはホストマシンのネットワークカードに関連付けられたIP
と、空いているport
である必要があります。もし、ローカルのIP
を指定する必要がなく、port
だけを指定したい場合は、代わりにNetAddress.Any(27015)
(0.0.0.0:27015
の意味) を使用します。これは、ホストファイアウォール 上で通信可能なポートが制限されており、特定のポートに固執する必要がある場合に適しています。
C#
NetworkRunner.StartGame(new StartGameArgs() {
GameMode = GameMode.Server,
Address = NetAddress.CreateFromIpPort("192.168.0.10", 27015) // or NetAddress.Any(27015)
// other args
});
- 事前に定義されたローカルおよびパブリックエンドポイント: 2のケースを拡張し、ピアのローカルエンドポイントとパブリックエンドポイントの両方を設定することができます。Fusionは、パブリックエンドポイントの検出にSTUNプロトコルを使用せず、引数として渡されたものだけを中継します。この例では、ピアはケース2と同じローカルエンドポイントにバインドしますが、特定のパブリックエンドポイント(
10.0.0.1:27030
)も使用します。CustomPublicAddress
引数は、ホスティングサービスがすでに Local と Public EndPoints の間のマッピングを提供しているシナリオで使用することを意図しています。
C#
NetworkRunner.StartGame(new StartGameArgs() {
GameMode = GameMode.Server,
Address = NetAddress.CreateFromIpPort("192.168.0.10", 27015),
CustomPublicAddress = NetAddress.CreateFromIpPort("10.0.0.1", 27030)
// other args
});
クライアントモード
通常のダブルクリックでアプリケーションを起動すると、ゲームウィンドウが開き、クライアント側のオプションが表示されます。
そこからは、以下のことを行えます。
セッション名
欄に記入して特定のゲームに参加するか、空欄のままランダムなゲームに参加する。- デフォルトの
ClientServer
ロビー、またはCustom Lobby
フィールドで指定したカスタムロビーに参加します。- ロビーに参加した場合、そのロビーで利用可能な
ゲームセッション
のリストが表示され、Join
ボタンをクリックすることでゲームに参加することができます。 - ロビーから
Shutdown
ボタンでNetworkRunner
をシャットダウンし、再度起動することも可能です。
- ロビーに参加した場合、そのロビーで利用可能な
ゲームサーバに接続すると、各クライアントは1人のプレイヤーを受け取り、通常のWASDで操作してレベル内を移動することができます。
クライアントはShutdown
ボタンをクリックすることでサーバーとの接続を解除することができます。