物理
Fusion 2.1から、ホスト/サーバーモードと共有モードの両方で、NetworkTransformでRigidbodyがサポートされるようになりました。
組み込みで2つの異なるアプローチに対応しています。
Forecast(有効):補外(extrapolation)を使用して、各プレイヤーのローカル時間で物理オブジェクトを動かすことで、スムーズなインタラクションを実現します。
Forecast(無効):非物理オブジェクトと同じ方法で、権限者の物理オブジェクトを他のクライアントに同期します。権限者を除き、オブジェクトはリモート時間となり、
Rigidbodyはキネマティックに設定されます。ホスト/サーバーモードにおいて、インタラクションが発生しない物理オブジェクトに最適です。
Network Project Config(グローバル設定)
Physics Forecast
これはForecast Physicsのグローバル設定です。Forecast Physicsの補外を有効にするには、これを有効にする必要があります。チェックを外すと、物理オブジェクトはリモート時間で各プロキシに同期されます。チェックを入れると、Forecast PhysicsがNetworkTransformごとに制御されます。
Network Transform(個別の制御設定)
Forecast Physics Enabled
オブジェクトごとのForecast Physics制御オプションです。NetworkProjectConfigでForecast Physicsが有効な場合のみ動作します。
Forecast(有効)
Forecast Physicsは、ネットワーク経由で受信した位置を補外し、物理オブジェクトを各プレイヤーのローカル時間に置きます。各プレイヤーはローカルで完全な物理演算を実行し、補外された位置を調整します。これによって、物理オブジェクト間のスムーズなインタラクションが可能になります。
オブジェクトをスムーズに動かすためには、UnityのRigidbodyの補間を有効にする必要があります。
Forecast PhysicsはFusionの特殊なケースで、Update()やFixedUpdateNetwork()ではなく、FixedUpdate()を使用する必要があります。車両の物理とFusionを組み合わせる例をご覧ください。
プレイヤーが制御する物理オブジェクト(例:車)の場合は、プレイヤーの入力をすべてのクライアントに送信し、各クライアントがローカルでオブジェクト制御コードと物理演算を実行する方が、一般的に良い結果が得られます。
Forecast Physicsでは、RigidbodyConstraints2D/RigidbodyConstraintsや、isKinematicは自動的に同期されます。他のプロパティ(例:mass)を同期したい場合は、以下のように手動で同期する必要があります。
C#
public class PhysicsController : NetworkBehaviour
{
[OnChangedRender(nameof(OnMassChanged))]
[Networked] FloatCompressed Mass { get; set; }
Rigidbody _rb;
void OnMassChanged() {
_rb.mass = Mass;
}
public override void FixedUpdateNetwork() {
Mass = _rb.mass;
}
}
制限
Unityの最新バージョンでは、物理演算をFixedUpdate()ではなくUpdate()で実行することが可能ですが、Forecast Physicsではサポートされていません。
受信データの補外は、ワールドの障害物を認識しません。物理演算はローカルで実行されるため、オブジェクトが壁や障害物に誤って侵入することはありませんが、動き回るオブジェクトは各クライアントで異なる位置に表示される可能性があります。この現象は、物理オブジェクトが急な方向転換を行うような場合(例:ボールが床で跳ね返る)に特に目立ちます。
他のネットワーク処理と同様に、クライアントのping増加に比例して物理の同期精度は低下します。
代替手段
物理演算をネットワーク化する最適な方法は、Fusionでキネマティックなキャラクターを予測・再シミュレーションするのと同じように、物理演算を予測・再シミュレーションすることです。
クライアントサーバー型のゲームでは、Fusionのアドオンを使用してこれを実現できます。ただし、Unityの物理エンジンは再シミュレーションに最適化されていないため、負荷が高いことに注意してください。Fusion 2.0のPhysicsアドオンなら、RunnerPhysicsSimulate2D/3DをSimulateAlwaysに、Physics AuthorityをFusionに、Physics TimingをFixedUpdateNetworkに設定してください。
Fusion 2.1のPhysicsアドオンは簡略化され、クライアントサーバー型のゲームの処理に特化しています。
別の選択肢として、ゲームの同期に異なるアプローチを採用し、予測と再シミュレーションに最適化された物理エンジンを備えたQuantumを使用することができます。
Forecast(無効)
非物理オブジェクトの同期と同じ方法で、権限者の物理オブジェクトを他のクライアントに同期します。デフォルトでは、プロキシのRigidbodyはキネマティックに設定され、すべての物理インタラクションは権限者側で処理されます。
これは、物理インタラクション不可能な(例:キャラクターが物理オブジェクトを押したりできない)クライアントサーバー型のゲームに適しています。 プロキシはリモート時間に置かれます。一般的に、物理オブジェクト間のインタラクションはスムーズに動作しません。
この挙動はFusion 2.1で変更されています(Fusion 2.0では、プロキシのRigidbodyがキネマティックに設定されていませんでした)。Fusion 2.0と同等の挙動にするには、コードからNetworkTransform.PhysicsSettings.SetForecastDisabledProxyRigidbodiesToKinematicプロパティをfalseに設定してください。