PlayerRef
概要
Fusionにおける「プレイヤー(Player)」とは、Fusionにプレイヤー入力を提供するNetworkRunner
を持つピアを指します。つまり、専用ゲームセッションサーバー以外の任意のピアです。
ここでは、プレイヤー情報を識別・取得するための様々な方法を示します。
PlayerRef
プレイヤーの入力を提供する各NetworkRunner
には、PlayerRef
と呼ばれるユニークな識別子が関連付けられています。プレイヤーに与えられるPlayerRef
は識別子としてのみ表され、プレイヤー個別のデータを一切含みません。
PlayerCount
この値は、ゲームセッションに接続できるプレイヤーの最大数です。
ゲームセッションごとの最大PlayerCount
のデフォルトは、NetworkProjectConfig
アセットのSimulation > Default Players
フィールドでグローバルに定義されています。
新しいゲームセッションを作成する際に、StartGameArgs.PlayerCount
の値がNetworkRunner.StartGame()
に渡されてPlayerCount
が決定されます。StartGameArgs.PlayerCount
に値が設定されていない(またはnullが設定されている)場合、新しいゲームセッションはNetworkProjectConfig
のDefault Player
の値をかわりに使用します。
専用サーバーはPlayerRef
を持たず、プレイヤーを表さないため、PlayerCount
の制限にはカウントされないことに留意してください。つまり、PlayerCount
が4のゲームセッションでは、以下のパターンが有効です。
- ホスト1人、クライアント3人
- 専用サーバー1つ、クライアント4人
- 共有モードのクライアント4人
Player Objectの定義
Player Objectは、ゲームセッションの各PlayerRef
に、特定のNetworkObject
(アバターなど)を関連付ける便利な方法です。
各PlayerRef
には、NetworkObject
を1つだけ関連付けることができます。この関連付けは、ネットワーク上のすべてのクライアント間で自動的に複製されます。
PlayerRef
とNetworkObject
の関連付けは、NetworkRunner.SetPlayerObject(PLayerRef, NetworkObject)
メソッドを使用して設定します。
- ホスト(サーバー)モード:Player Objectは、ホスト/サーバーでのみ設定できます
- 共有モード:各プレイヤーは自身のPlayer Objectの関連付けのみを設定でき、プレイヤーは関連付ける
NetworkObject
の状態権限を持っている必要があります
すべてのピアは、NetworkRunner.TryGetPlayerObject(PlayerRef, out NetworkObject)
メソッドから、特定のPlayerRef
に関連付けられたNetworkObject
を取得できます。
C#
// On Player Joined, create and define a Player Object.
void OnPlayerJoined(PlayerRef player, NetworkRunner runner){
if (Object.HasStateAuthority == false) return;
var plObject = runner.Spawn(PlayerObjectPrefab);
var plData = plObject.GetComponent<PlayerData>();
//SetData defines the PlayerRef for that NB and a life amount.
plData.SetData(player, 3);
runner.SetPlayerObject(player, plObject)
}
// When desired, get the Player Object.
int GetPlayerLife(PlayerRef player){
if (Runner.TryGetPlayerObject(player, out var plObject)){
return plObject.GetComponent<PlayerData>().Lifes;
}
Debug.LogError("Player Object Not found")
return 0;
}
状態権限(State Authority)
各NetworkObject
は、StateAuthority
として関連付けられたPlayerRef
を持ちます。StateAuthority
は、NetworkObject
の状態(ネットワークプロパティ)を管理します。状態権限者によって変更されたネットワークプロパティは、ネットワークを介して他のクライアントに複製されます。
- ホスト(サーバー)モード:常にホスト/サーバーが状態権限を持ち、他のプレイヤーは状態権限を持てません。
- 共有モード:権限はプレイヤー間で分散・共有されます。すべてのプレイヤーは、任意のオブジェクト(状態権限者が割り当てられていない、または
Allow State Authority Override
がtrue
に設定されている)に対する状態権限を持つことが可能です。状態権限が割り当てられるのは、オブジェクトがスポーンした時と、NetworkObject.ReleaseStateAuthority()
とNetworkObject.RequestStateAuthority()
を呼び出して手動で変更した時です。
入力権限(Input Authority)
NetworkObject
は、StateAuthority
に加えてInputAuthority
を持つことができます。InputAuthority
は、ホスト(サーバー)モードにのみ関連します。
プレイヤーは、複数のNetworkObject
に対して入力権限を持つことができます。NetworkObject
に対する入力権限を持つプレイヤーは入力を送信し、サーバーはNetworkObject
の入力が必要になった時にその入力を取得します。これがクライアントからサーバーへの主要な通信手段になります。入力の詳細はプレイヤー入力をご覧ください。
1端末で複数のローカルプレイヤー
1つのNetworkRunner
で1人以上の物理的なプレイヤーがいるゲーム(例:オンライン上のプレイヤーとも協力できる画面分割のゲーム)の場合、Fusionの「プレイヤー」の概念とは独立してローカルプレイヤーを区別するゲーム固有のロジックが必要になります。複数のローカルプレイヤーからの入力すべてを、Fusionの入力システムで集約し、一つの入力構造体にすべてのローカルプレイヤーの入力データを格納します。
備考: 複数のローカルプレイヤーを持たせながら、PlayerRef
・SetPlayerObject
・OnPlayerJoined
などの機能を使用する場合は、独自のロジックを追加する必要があります。