网络拥有

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

为了支持玩家体验的复杂机理,同时也为了实现光滑和响应的体验,Roblox 的 物理引擎 使用了一个 分布式物理系统 ,在服务器和所有连接的客户端之间进行计算。 在此系统中,引擎将 网络拥有 分配

客户端体验 更有弹性的物理互动与零件,因为与服务器通信无延迟。 网络拥有也会提高服务器性能,因为物理计算可以在多个客户端之间分布,从而服务器可以优先处理其他任务。

基础部件所有者

默认情况下,服务器保留所有BasePart 的所有权。 另外,服务器 总是 拥有锚定的BaseParts ,您无法手动更改其所有权。

根据客户端的硬件容量和玩家的 Player.Character 邻近度,引擎自动分配该部分的所有权给客户。因此,靠近玩家角色的零件的几率更高。

装配拥有

如果一个基于物理机制的机制没有锚定零件,设置所有者在该机制内的装配中设置同一的所有者为 每个装配 在机制内。

如果您在广义机制的不是部分的独立组合中 Anchor 一个 lone 组合,其所有权将归服务器,因为服务器总是拥有anchored BaseParts 。 在 unanchoring 同一组合时,其以前的所有权状态会丢失,并且它恢复到引擎自动处理。

如果您将一个组合体结合到更广泛的机器中,其所有权将归服务器,但其他组合体的所有权将保持不变。未锚定相同的组合体将恢复以前设置的所有权。

设置所有者

在复杂物理互动体验或在需要直接控制的情况下,您可以通过服务器端的调用 BasePart:SetNetworkOwner() 来设置所有者。

考虑有一个车辆,其中包含VehicleSeat 对象为司机,以及Seat 对象为乘客,其中包含在车辆组合中。

下列 Script 修复了这个通过手动分配网络所有者到驾驶员。它在内含 Class.VehicleSeat.Occ


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
-- 重置座位 when 不在使用中
vehicleSeat:SetNetworkOwnershipAuto()
end
end
end)

显示所有者

Studio 可以在游戏测试时在对象周围渲染颜色轮廓,以帮助调查网络拥有问题。

外部色描述
(绿色)您的客户拥有零件并正在模拟它。
(红色)零件位于一个“缓冲区”中,您的客户正在模拟它,但它仍然属于另一个东西。您的客户可能会在此后获得所有权,或者它可能会拒绝。

(白色/灰色)服务器或其他客户通过自动网络拥有部分或通过 part:SetNetworkOwner() 的明示授权获得部分。

要启用网络所有者视图:

  1. 点击3D视图的上右角中的 视觉选项 按钮。

    A close up view of the 3D viewport with the Visualization Options button indicated in the upper-right corner.
  2. 在下拉菜单中,切换 网络所有者

安全考虑

Roblox 无法验证客户端拥有BasePart 时是否验证物理计算。客户端可以利用此情况并向服务器发送垃圾数据,例如传送BasePart,使其穿过墙壁或飞行。

此外, BasePart.Touched 事件与网络所有者关联,意味着客户端可以在Touched 它拥有和发送到服务器,即使服务器未见到触摸任何东西。例如,客户端可以通过脚本注

有关 Roblox 体验的详细安全技术和漏洞 mitigation,请参阅安全战术和漏洞 mitigation