複雑な物理メカニズムをサポートしつつ、プレーヤーにスムーズで応答性の高い体験を提供するために、Robloxの物理エンジンは、計算がサーバーと接続されたすべてのクライアント間で分散される分散物理システムを利用しています。このシステム内で、エンジンは物理的にシミュレートされたBasePartsのネットワーク所有権をクライアントまたはサーバーのいずれかに割り当て、物理計算の作業を分担します。
クライアントは、自分が所有しているパーツとの物理的相互作用がより応答性が高いと感じます。これは、サーバーとの通信による遅延がないためです。ネットワーク所有権は、物理計算を個々のクライアント間で分割できるため、サーバーのパフォーマンスも向上させます。これにより、サーバーは他のタスクを優先できるようになります。
BasePartの所有権
デフォルトでは、サーバーはすべてのBasePartの所有権を保持します。さらに、サーバーは常に固定されたBasePartsを所有しており、その所有権を手動で変更することはできません。
クライアントのハードウェアの能力やプレーヤーのPlayer.Characterが固定されていないBasePartに近い場合、エンジンはそのパーツの所有権を自動的にクライアントに割り当てます。したがって、プレーヤーのキャラクターに近いパーツは、プレーヤー所有になる可能性が高くなります。
アセンブリの所有権
物理に基づくメカニズムに固定されたパーツがない場合、そのメカニズム内のアセンブリに所有権を設定することは、そのメカニズム内のすべてのアセンブリに同じ所有権を設定します。
より広範なメカニズムの一部でない孤立したアセンブリを固定すると、その所有権はサーバーに移ります。これは、サーバーが常に固定されたBasePartsを所有するためです。固定された同じアセンブリの固定を解除すると、以前の所有権状態は失われ、エンジンによる自動処理に戻ります。
広範なアセンブリのメカニズム内の一つのアセンブリを固定すると、そのアセンブリの所有権はサーバーに移りますが、他のアセンブリの所有権は変更されません。同じアセンブリの固定を解除すると、以前に設定された所有権に戻ります。
所有権の設定
複雑な物理的相互作用のあるゲームや、直接的な制御を設定する必要がある場合は、BasePart:SetNetworkOwner()を介してサーバー側で所有権を設定できます。
運転者用のVehicleSeatオブジェクトと乗客用のSeatオブジェクトを持つ車両を考えてみましょう。この二つのオブジェクトは車両アセンブリに含まれています。デフォルトの所有権ルールでは、プレイヤーキャラクターがSeat(乗客)に座り、別のプレイヤーがVehicleSeat(運転手)に飛び込むと、乗客は最初に入ったため、車両全体の物理所有権を獲得します。運転手は、入力が認識されるまでに数回のネットワークサイクルを待たなければならず、そのため車両は応答性が低く感じられます。
以下のScriptは、運転手にネットワーク所有権を手動で割り当てることでこれを修正します。このスクリプトでは、VehicleSeatがそのOccupantをその上に座っているHumanoidに設定し、スクリプトはシートのChangedイベントをリスンしてプレイヤーがシートに座った時を捕捉します。運転手がシートを離れると、車両のネットワーク所有権はBasePart:SetNetworkOwnershipAuto()によって自動処理に戻ります。
local Players = game:GetService("Players")
local vehicleSeat = script.Parent
vehicleSeat.Changed:Connect(function(prop)
if prop == "Occupant" then
local humanoid = vehicleSeat.Occupant
if humanoid then
-- キャラクターからプレイヤーを取得する
local player = Players:GetPlayerFromCharacter(humanoid.Parent)
if player then
vehicleSeat:SetNetworkOwner(player)
end
else
-- シートが空のときに所有権をリセット
vehicleSeat:SetNetworkOwnershipAuto()
end
end
end)
所有権の可視化
ネットワーク所有権のデバッグを支援するために、スタジオはプレイテスト中にオブジェクトの周囲に色付きのアウトラインを描画できます。
| アウトラインの色 | 説明 | |
|---|---|---|
| (緑) | あなたのクライアントがそのパーツを所有し、シミュレートしています。 | |
| (赤) | そのパーツは「バッファゾーン」にあり、あなたのクライアントはそれをシミュレートしていますが、まだ別のものに所有されています。この後、あなたのクライアントが所有権を獲得する可能性があるか、拒否される場合があります。 | |
| (白/灰色) | サーバーまたは別のクライアントが、ネットワーク所有権の自動割り当てまたはpart:SetNetworkOwner()によってそのパーツを所有しています。 | |
| (黒) | そのパーツはサーバーにもクライアントにも所有されていません。物理がこのパーツに適用されることはありません。 | |
ネットワーク所有権の可視化を有効にするには:
3Dビューポートの右上隅にある可視化オプションボタンをクリックします。

ドロップダウンメニューで、ネットワーク所有者をオンにします。
セキュリティの懸念
Robloxは、クライアントがBasePartの所有権を持っている際に物理計算を検証することはできません。クライアントはこれを利用して、BasePartをテレポートさせたり、壁を通り抜けさせたり、空中を飛ばしたりといった不正なデータをサーバーに送信できます。
さらに、BasePart.Touchedイベントはネットワーク所有権に関連付けられており、クライアントは所有しているBasePartでTouchedイベントを発火させ、サーバーに送信できます。サーバーがその接触を認識しなくてもです。たとえば、クライアントはスクリプトインジェクションを通じてイベントを発火させ、マップの反対側にいる別のプレイヤーにダメージを与えることができます。そのため、クライアントが発火させたそのようなイベントの有効性を確認することが重要です。
詳しいセキュリティ戦略や不正行為の軽減策については、Security Tactics and Cheat Mitigationをご覧ください。