新機能紹介
Fusion 1は、業界をリードする状態同期ネットワークライブラリという高い目標を設定し、BoltとPUNの優れた特徴とノウハウを融合させました。この独自のアーキテクチャによって、Fusionは非常に幅広いゲームジャンルをカバーできるようになり、CPUや帯域幅の使用量の劇的な削減もあいまって、真の次世代ネットワークライブラリが実現しました。
Fusion 2はFusion 1をベースに、新機能の追加や既存のAPIをより使いやすくする更新が盛り込まれています。さらに、Fusionの内部構造を無駄なく改良するためにコア実装の大部分が書き直されています。データ転送・時間の同期・メモリ管理・全体的なCPUパフォーマンスなど、手を加えた変更は広範囲に及びます。
このページはFusion 2で加えられた変更点の概要です。
インタレストマネジメントの再実装
新しいインタレストマネジメントシステムはより効率的になり、オブジェクトが関心対象に出入りした時に呼ばれるEnter/Exitコールバックが追加されます。
コールバックは、ネットワークオブジェクトが特定のプレイヤーのAOI領域に出入りした時、プレイヤーがオブジェクトを明示的に関心対象に追加・削除した時に(Runner.SetPlayerAlwaysInterested()
を使用して)呼び出されます。これらは、各モード(サーバーモード・ホストモード・共有モード)のサーバー上で計算され、信頼性があります。
また、NetworkObject/NetworkBehaviour.ReplicateTo
というAPIで、どのオブジェクトがどのクライアントにレプリケーションされるかを動的にきめ細かく制御できます。
プロキシ上のFixedUpdateNetwork
デフォルトでFixedUpdateNetwork
はプロキシ上では実行されなくなりました。(プロキシとは、クライアント上でそのクライアントが入力権限を持たないネットワークオブジェクト)
この変更により、プロキシのシミュレーションを必要としない多くのアプリケーションで、全体的なCPU使用量が削減されます。プロキシのシミュレーションを必要とするケース(物理オブジェクトの予測を使用する場合など)では、以下のようにして、プロキシ上でFixedUpdateNetwork
が実行されるように設定できます。
C#
networkRunner.SetIsSimulated(networkObject, true);
新しい時間の同期
Fusion 2では、クライアントがどの程度先のティックを予測し、どの程度の長さのサーバーのスナップショットの履歴を保存するかを制御するシステムが改善されました。新システムはFusion 1.1と比較して、ネットワーク状況の変化にスムーズに適応しながら、非常に高速で信頼性があります。
設定もよりシンプルでわかりやすくなります。パケットロスの許容割合と追加の固定オフセットの二つの設定で、クライアントの予測幅とスナップショット履歴の保存期間が決まります。システムは直近のネットワーク状況をサンプリングして、動的にクライアントの予測幅を調整します。ジッターが増加すると、クライアントはより先のティックを予測するようになり、そこからまたジッターが減少すると、クライアントの予測幅は小さく戻ります。固定オフセットは、本質的に「送信試行回数」です。
例えば、クライアントの入力が遅れてサーバーに到達する割合を1%以下に抑えて、各入力にセカンドチャンス(最初のパケットが失われた場合に再送信できる機会)があるのが望ましいなら、TimeSyncConfiguration.MaxLateInputs
を1
に、 TimeSyncConfiguration.ExtraSimulationOffset
を1
に設定してください。
共有モードの改善
共有モードでも、クライアント間のティックが正確になりました。
Runner.Tick
を使用して、クライアント共通の特定のティックを参照できるようになり、TickTimer
にも対応します。
また、共有モードでもホストモードと同精度のスナップショット補間が使用できるようになったため、同期ズレや体感のラグが軽減されます。
変更検知(Change Detection)
新しい変更検知APIによって、Render
での変更の検知だけでなく、FixedUpdateNetwork
でのゲームプレイロジックの判定のトリガーにも使用できるようになりました。
ChangeDetector
は以下のように作成します。
C#
_changes = GetChangeDetector(ChangeDetector.Source.SimulationState);
ChangeDetector
のDetectChanges
メソッドは、いつでも(FixedUpdateNetwork
でもRender
でも)変更を検知できます。
新しいネットワークデータアクセスシステム
Fusion内部のデータバッファに直接アクセスするAPIもあります。TryGetSnapshotsBuffers
でスナップショットのバッファにアクセスして、そのデータを読んだり、カスタムの補間に使用したりすることが可能です。
Interpolation Target
Fusion 1のInterpolation Target
は、正しく扱うことが困難な場合(特にネットワークオブジェクトをネストした時など)がありました。Fusion 2では補間がシンプルになりました。Interpolation Target
は削除されて、かわりにNetworkTransform
が追加されているオブジェクト自体のTransform
が補間されます。
NetworkTransformの改善
NetworkTransform
のTRSデータ(Position/Rotation/Scale)は、ローカル座標系で格納されるようになりました。
- 子要素やネストした
NetworkTransform
のデータ効率が大幅に向上 - ネストした
NetworkTransform
のAOIの位置は無効になるが、NetworkObject
はAreaOfInterestOverride
から別のNetworkObject
の位置を指定して、プレイヤーの関心対象を決定することができる
また、transform.localScale
を任意で同期できるようになりました。
さらに、NetworkObject
の親(Parent)を任意で同期できるようになりました。親には有効なNetworkBehaviour
が存在し、NetworkTransform
はネットワークオブジェクトのルートにある必要があります。
物理演算のネットワーク対応
Fusion 1のSDKにはNetworkRigidBody
とNetworkPhysicsSimulation
が含まれていましたが、これらはFusionのDLLから削除され、アドオン(Unity Physics Addon)に置き換わります。既存のServer Only
モードとClient Prediction
モードに加えて、Forward Only
モードが追加される予定です。
アドオンはソースコードで提供しているので、プロジェクトのニーズに合わせて修正・拡張することができます。そのため、VRゲームのような複雑なユースケースでも、より柔軟に物理演算を動作させることができます。Fusion 2ではNetworkTransform
からInterpolation Target
が削除されましたが、NetworkRigidbody
にはInterpolation Target
プロパティが残されています。ただし、Interpolation Target
が必要になるのは非常に特殊なユースケースのみになるため、通常はnull
のままで問題ありません。
VR向けの入力モード
VRゲームのために、新しい入力転送モードが設計されました。Fusionのデフォルトでは、サーバーへ送信するクライアントの入力には信頼性がありません。そのため、パケットロスの影響を緩和するために、各入力のパケットには短い過去の入力履歴が含まれます。既存のモードは多少のパケットロスが発生しても、サーバーは完全な入力列を処理することができますが、それだけ入力のパケットサイズは増加してしまいます。
VR入力モードでは最新の入力のみを送信するため、頭・手の位置データを含むサイズが大きい入力構造体が必要なVRゲームの帯域幅を劇的に削減できます。
これを有効にするには、NetworkProjectConfig
のInput Transfer Mode
をLatest State
に設定してください。
暗号化
Fusion 2で導入されるシームレスなエンドツーエンド暗号化によって、ゲームプレイ通信のセキュリティが保証されます。クライアントとPhoton Cloud間の通信をカバーする暗号化システムは既存のRealtime SDK上で構築されていて、Fusion 2では、クライアントとサーバー間のデータ通信の自動的な暗号化と、その機能を簡単に有効化できる方法が追加されます。共有モードでもホストモードでも、ピア間で通信されるデータパケット全体を暗号化することで、セキュリティを強化する堅牢な暗号化ソリューションを提供します。
Simple KCC
Simple KCCは、ユーザーフレンドリーで直感的に使用できる3D Character Controllerアドオンです。これは、Fusionを使用したゲームプロジェクトで、簡単にキャラクターを移動させられるよう設計されています。
Simple KCCは、UnityのCharacterController
より多機能で、あらゆるマルチプレイのユースケースに対応しており、共有モードでもホストモードでも使用することができます。
新しいヒープシステム
Fusion 2はメモリを事前に割り当てる新しい内部ヒープを備えていて、Fusionで使用される内部のアンマネージドメモリのリーク検知やガベージコレクションが可能です。
データ転送モードの統合
Fusion 1では、二つのデータ転送モード(デルタスナップショットと結果整合性)を提供していて、ユースケースに応じてどちらかを選択するものでした。しかし、一つのモードに焦点を当てることで、ほぼ全てのユースケースで、CPUや帯域幅の使用量がより効率的なデータ転送モードを提供できることがわかりました。
新しい結果整合性モードは、パフォーマンスが大幅に改善しただけでなく、各クライアントが同一のティックで受信したNetworkObject
のNetworked Property
の全ての更新は、ティックに正確に一致したデータを(オブジェクトごとに)返すことがデフォルトで保証されます。以前の(プロパティごとの)結果整合性モードを使用したい場合は、SimulationConfig.ObjectDataConsistency
をEventual
に設定してください。
シーン管理
様々なケースに標準で対応するため、シーン管理は完全に書き直されました。UnityのSceneManager
を簡単に差し替えられるようになったため、より複雑なシーン遷移の構築も可能になりました。
Addressableなシーンに対応するコードを書く必要はなくなりました。単純にAddressablesのラベルFusionScenes
をAddressableなシーンに追加すると、Fusionは自動的にそのシーンを認識します。
Additiveなシーンのロードも可能になりました。NetworkSceneInfo
は最大8つ同時のシーンに対応し、シングルピアモードでもマルチピアモードでも動作します。
クライアントは単純にシーンをアンロードした後に再びロードすることで、シーンを再ロードすることも可能です。
加えて、オブジェクトはDontDestroyOnLoad
でスポーンするようになりました。これは、マルチピアモードやAdditiveなシーンでも同様です。
Fusion 2のApp ID
Fusion 2のアプリケーションは、ダッシュボードから、Fusion 2のApp IDを明示的に作成する必要があります。
詳細は、共有モード入門 - App IDを作成するをご覧ください。
新しいデモメニュー
プロトタイピング用のテンプレートを提供する新しいデモメニューからFusionの開発を始めることができます。
ここでは、ランダムなマッチメイキングや、部屋コードを共有するプライベートなマッチメイキングなど、一般的に使用される機能を確認できます。
デモメニューは拡張可能性と、接続ロジックの複雑性をバランスよく扱えるよう設計されています。
ラグ補償
ラグ補償が改善されました。過去のレンダリング情報から正しく補間されたアニメーション位置を自動的に使用するようになったため、レンダリング前にアニメーションのヒットボックスを調整する必要が無くなりました。
さらにラグ補償は、2Dの物理シーンに対するクエリに対応するようになりました。
加えて、3D Capsuleのヒットボックスにも対応しました。
NetworkObjectProvider
INetworkObjectPool
はINetworkObjectProvider
に置き換えられ、より一貫性のある完全なAPIになりました。デフォルトの実装で、非同期でオブジェクトのロードとスポーンが可能です。
新機能に適応するため、NetworkRunner.TrySpawn
と、awaitableなNetworkRunner.SpawnAsync
メソッドが追加されています。Addressablesは、プリロードしたりWaitForcompletion
を待ったりする必要がなくなりました。
未使用のAddressableのプレハブは、インスタンス数が0になった後、NetworkRunner.Prefabs.UnloadUnreferened
で任意にアンロードできるようになりました。
これらはNetworkPrefabsInspector
ウインドウから、どのプレハブがロードされているか、スポーンしているか、スポーンしているならインスタンス数はいくつか、などを確認できます。
SendReliableData
信頼性のあるデータストリーミングAPIが再実装されて、様々な使いやすい改善がもたらされました。クライアントへのストリームデータは自動的にフラグメントに分割・再結合されます。また、完全なデータの受信に関連して呼び出されるコールバックや、データ転送のステータスを追跡するコールバックが提供されています。
以下はコードの例です。
C#
byte[] largeData = new byte [10000];
// Provide 4 numbers as a unique key for the data
var key = ReliableKey.FromInts(42, 0, 0, 0);
// Use in shared mode or as the server/host to send data to players
runner.SendReliableDataToPlayer(playerRef, key, largeData);
// Use as a client to send data to the server/host
runner.SendReliableDataToServer(key, largeData);
データ受信時のINetworkRunnerCallbacks
のコールバック:
C#
public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, ReliableKey key, ArraySegment<byte> data){}
public void OnReliableDataProgress(NetworkRunner runner, PlayerRef player, ReliableKey key, float progress){}
Back to top