PUN2からの移行
概要
ここでは、オブジェクト同期とゲームプレイに焦点を合わせて、PUN経験者がFusionを習得する方法を説明します。
PUNは非常に完成度が高く使いやすいネットワークエンジンですが、時代が進むにつれて、大人数のプレイヤー数・プレイヤーのアクションに対する正確なレプリケーション・権限処理など、現代的なマルチプレイヤーゲームには不十分な面も出てきました。Fusionは、PUNと同様の使いやすさで、多くのプロジェクトに適したものになるでしょう。
Fusionのモード
PUNからFusionに移行する際に理解しておくべき重要な点は、PUNは、すべてのクライアントに共有されているルームによる「分散型」の権限モデルであることです。
Fusionを共有モードで実行すると、PUNと同じ分散型権限モデルになります。シーンオブジェクトは、自動的に1人のプレイヤーによって制御されます。PUNのほとんどの概念は、Fusionの共有モードに応用可能ですが、Fusionのホスト(サーバー)モードには応用できません。
ここでは、PUNの知識をFusionの共有モードへ移行する方法を説明します。ホスト(サーバー)モードは、アプリケーションによっては、より良い選択肢となります。
相違点
対応表
PUN | Fusion |
---|---|
PhotonNetwork | SimulationBehaviour.Runner と SimulationBehaviour.Object |
MonoBehaviourPunCallbacks | SimulationBehaviour と NetworkBehaviour |
PhotonNetwork.AddCallbackTarget(this) | N/A (自動) |
PhotonNetwork.Instantiate() | Runner.Spawn() |
PhotonView | NetworkObject |
IPunObservable.OnPhotonSerializeView() | C#の自動実装プロパティ と 入力の同期 |
PhotonTransformView | NetworkTransform |
PhotonRigidbodyView | NetworkRigidbody |
PhotonAnimatorView | NetworkMecanimAnimator |
N/A | NetworkCharacterController |
[PunRPC] | [Rpc] |
PhotonNetwork.LoadLevel() | Runner.SetActiveScene() |
接続とマッチメイキング
マッチメイキングの主要概念は、PUNとFusionで同じです。ロビー・マッチメイキング・ルーム・マッチメイキング用のプロパティなどは、Fusionにも存在します。
FusionのマッチメイキングAPIは完全に異なり、NetworkRunner
から呼び出して使用します。Fusionにおける接続とマッチメイキングの詳細は、こちらをご覧ください。
設定ファイル / ConnectUsingSettingsの代替
PUNの多くの設定は、PhotonServerSettings
ファイル(ScriptableObject)に格納されています。設定は主に、AppId
・サーバー設定・プロトコル・ログなどについてです。
Fusionでは、設定が2つのファイルに分けられています。
PhotonAppSettings
が保持する情報は、クライアントがPhoton Cloudに接続するために使用されます。設定を変更する必要があるデータは、アプリケーションのAppId
のみであることがほとんどです。AppId
はFusion Hubからも設定できます。
NetworkProjectConfig
では、Fusionに関する多くのオプションを詳細に設定できます。デフォルトの設定のままでも使用できます。設定には、ティックレート・最大プレイヤー数などがあります。
認証
PUNと同じように、Fusionは認証プロバイダーに対応しています。詳細はカスタム認証のページをご覧ください。
オフラインモード
PUNのように、Fusionにもオフラインモードがあります。PhotonNetwork.OfflineMode
のかわりに、NetworkRunner.StartGame
呼び出し時にGameMode.Single
を使用してください。
ActorNumber
PUNでは、新規プレイヤーごとにPlayer.ActorNumber
がカウントアップされていました。Fusionでは、PlayerRef
が0
からMaxPlayers - 1
までカウントアップします。ゲームにホストが存在する場合、ホストプレイヤーのPlayerRef
の値は常にMaxPlayers - 1
になります。
NetworkRunner(PhotonNetworkの代替)
PUNの多くのAPIはPhotonNetwork
クラスから利用可能でした。FusionはNetworkRunner
がインスタンスごとに存在します。NetworkBehaviour
を継承したクラスは、NetworkRunner
とNetworkObject
にアクセスできるため、FusionのAPIはPUNと同じくらい簡単に使用できます。
UnityのヒエラルキーのコンテキストメニューにFusionのサブメニューがあり、シーン構成に便利なショートカットがあります。
コールバック(MonoBehaviourPunCallbacks / PhotonNetwork.AddCallbackTarget(this))
コールバックはPUNのAPIを支える要素で、接続の確立やランダムマッチメイキングの結果を待つために使用されます。PUNのコールバックは、いくつかのインターフェースの定義に分類されていて、それをスクリプトで実装します。そして、スクリプトを登録して、実行時にコールバックを受け取れるようにする必要があります。
PUNのMonoBehaviourPunCallbacks
クラスを継承すると、特定のメソッドをオーバーライドしてコールバックを受け取れるようになるため、このワークフローを単純化できます。
FusionはINetworkRunnerCallbacks
によって、セッション関連などのコールバックを提供します。Spawned
/Despawned
などのようなオブジェクト固有のコールバックは、NetworkBehaviour
から直接利用可能です。
インスタンス化
Fusionでは、PhotonNetwork.Instantiate()
のかわりにRunner.Spawn()
を呼び出します。オブジェクトプールには、独自のIPunPrefabPool
のかわりにINetworkObjectProvider
を使用します。
シーンオブジェクト
シーンオブジェクトは、PUNとFusionで同じような形で動作します。シーンが最初にロードされた時、マスタークライアントが、すべてのシーンオブジェクトの状態権限(StateAuthority
)を自動的に持ちます。
手動インスタンス化
FusionでPUNの手動インスタンス化を置き換えるためには、独自のINetworkPrefabSource
から、スポーンに必要なプレハブを提供します。特定のネットワークオブジェクトインスタンスを作成するPUNとは異なり、プレハブのインスタンス化はINetworkObjectProvider
によって行われます。
これは一般には非推奨で、ほとんどのFusion製アプリケーションには必要ありません。
シーン
シーンをロードするには、PhotonNetwork.LoadLevel()
をRunner.LoadScene()
に置き換えてください。
複数のシーン
Fusionは標準で、複数のシーンに対応しています。Runner.LoadScene()
でAdditiveなシーンローディングが可能です。
PhotonView
PUNの重要な要素であるPhotonView
と全く同等なクラスは、NetworkObject
と呼ばれます。PUNと同じように、NetworkObject
は単なる識別子(ID)であり、任意の振る舞いは追加したコンポーネントに依存します。
MonoBehaviourPun
MonoBehaviourPUN
は、FusionではNetworkBehaviour
になります。NetworkBehaviour
は、NetworkObject
と同じGameObject
および子のGameObject
に追加できます。
Fusionは、複数のNetworkObject
の入れ子に完全に対応しています。
PhotonTransformView
PhotonTransformView
はNetworkTransform
に置き換えられます。NetworkTransform
は、洗練された実装と多くの機能(親子関係の同期など)を、標準で搭載しています。
PhotonAnimatorView -> NetworkMecanimAnimator
PhotonAnimatorView
はNetworkMecanimAnimator
に置き換えられます。NetworkMecanimAnimator
は、PUNと同じように動作し、StateAuthority
を持つクライアントから他すべてのクライアント(プロキシ)へ、アニメーションを同期します。
CharacterController
PUNでは、プレイヤーキャラクターを動かすために、Unity標準のCharacterController
を使用できました。Fusionの共有モードでは、多くの機能を備えた上位オプションとしてSimple KCCアドオンも利用可能です。
PhotonRigidbodyView -> NetworkRigidbody
Fusionには、PUNと同様に動作するネットワーク物理システムがあります。PhotonRigidbodyView
のかわりにNetworkRigidbody3D
コンポーネントを使用してください。オブジェクトの権限を持つクライアントは、Rigidbodyに対して物理シミュレーションを実行し、他すべてのクライアントは、Rigidbodyに対してビューを表示するだけのKinematicな動作になります。物理コンポーネントは2Dでも利用可能です。
PhotonRigidbodyView
はNetworkRigidbody
に置き換えられ、PhotonTransformView
はNetworkTransform
に置き換えられます。どちらもPUNと同じように、2Dで利用可能です。
PhotonView.IsMine / オブジェクトの権限
PUNでは、クライアントがオブジェクトを操作するかどうかを決定するために、スクリプトでphotonView.IsMine
をチェックすることが一般的でした。Fusionでは、photonView.IsMine
がObject.HasStateAuthority
になります。
プレイヤー切断時の所有権移譲
PUNでは、所有者がいないネットワークオブジェクトに対して、マスタークライアントが変更された時に、自動的に新しいマスタークライアントに管理権限が移っていました。
Fusionでは、クライアントがルームから切断/退出した時の権限の移譲処理に、複数の選択肢が存在します。
NetworkObject
のIsMasterClientObject
を有効にすると、PUNの挙動と同じように、StateAuthority
が自動的に新しいマスタークライアントに移譲されるようになります。
Destroy When State Authority Leaves
を有効にすると、権限を委譲するかわりにオブジェクトを破棄します。
RPC
可能な限り、変数の同期(ネットワークプロパティ)を使用してください。
リモートプロシージャコール(RPC)は洗練されていて、[Rpc]
属性を付けたメソッドを、ローカルのメソッドのように呼び出すだけになりました。呼び出しは、ネットワークを通して動作するようにFusionによって変換されます。
カスタムプロパティにかわる変数の同期方法
PUNのカスタムプロパティは、Setterメソッドを持つハッシュテーブルでしたが、Fusionでは通常のC#プロパティが同期できます。NetworkBehaviour
内で[Networked]
属性を付けた自動実装プロパティは、ゲームの状態の一部となります。オブジェクトの権限者のみが値を変更でき、それが自動的にネットワークを通して複製されるため、チートのリスクが軽減されます。
プレイヤーのカスタムプロパティを置き換えるには、単純にNetworkBehaviour
にネットワークプロパティを追加してください。
ルームのカスタムプロパティを置き換えるには、シーンオブジェクトを作成し、そのNetworkBehaviour
にネットワークプロパティを追加してください。シーンオブジェクトは、FindObjectOfType
やシングルトンパターンなどを使用して取得できます。
IPunObservable.OnPhotonSerializeView()は不要に
OnPhotonSerializeView
もネットワークプロパティに置き換えられます。ネットワークプロパティは、OnPhotonSerializeView
とカスタムプロパティの両方の機能を兼ね備えています。ティックに合わせて即時に更新され、変更があった時のみ同期され、変更を検知するコールバックが利用可能です。
Fusion 2の変更検知
PUNでは、ルーム/プレイヤーのプロパティが変更されると、PropertyChanged
イベントが発生します。Fusionでは、OnChangeRender
かChangeDetector
が使用できます。
マルチピア
Fusionは1つのプロセスで、複数のNetworkRunner
インスタンスを実行して、テストやデバッグが可能です。エディター上のパネルから、可視化する/入力を取得するインスタンスを選択できます。
エディターで複数のピアを同時に実行すると、ピア開始時に現在のシーンがリロードされます。これに対応するように、ゲームロジックを修正する必要があります。PUNのように、スタンドアロンビルドからエディターに簡単に接続することができます。
特殊なケース
Fusionの共有モードは、PUNと同等の柔軟性と使いやすさを備えています。しかし、ハイペースな対戦ゲームなどに向けて、Fusionはホスト(サーバー)モードを提供しています。
このモードでは、サーバーまたはクライアントの1人が、ゲームの状態に対するすべての権限を持ちます。つまり、そのピアがすべての状態を保持し、そのピアのみが状態を変更できるということです。他のピアは、ローカルの予測や遅延を隠蔽するために状態を変更できますが、変更を有効にするにはサーバーから複製される必要があります。
自身のゲームでホスト(サーバー)モードを選択すべきかどうかを検討する際は、以下のQuadrantをご覧ください。
- 概要
- Fusionのモード
- 相違点
- 対応表
- 接続とマッチメイキング
- 設定ファイル / ConnectUsingSettingsの代替
- 認証
- オフラインモード
- ActorNumber
- NetworkRunner(PhotonNetworkの代替)
- コールバック(MonoBehaviourPunCallbacks / PhotonNetwork.AddCallbackTarget(this))
- インスタンス化
- シーンオブジェクト
- 手動インスタンス化
- シーン
- 複数のシーン
- PhotonView
- MonoBehaviourPun
- PhotonTransformView
- PhotonAnimatorView -> NetworkMecanimAnimator
- CharacterController
- PhotonRigidbodyView -> NetworkRigidbody
- PhotonView.IsMine / オブジェクトの権限
- プレイヤー切断時の所有権移譲
- RPC
- カスタムプロパティにかわる変数の同期方法
- IPunObservable.OnPhotonSerializeView()は不要に
- Fusion 2の変更検知
- マルチピア
- 特殊なケース