복잡한 물리 메커니즘을 지원하면서도 플레이어에게 부드럽고 반응이 빠른 경험을 제공하기 위해 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 이벤트를 발생시켜 서버에 보낼 수 있습니다. 서버가 접촉하는 것을 보지 못하더라도 말이죠. 예를 들어, 클라이언트가 스크립트 주입을 통해 이벤트를 발생시켜 지도의 다른 플레이어에게 피해를 줄 수 있으므로 클라이언트가 발생시킨 그러한 이벤트의 유효성을 확인하는 것이 중요합니다.
자세한 보안 전술과 Roblox 게임의 치트 완화 전술에 대해서는 보안 전술 및 치트 완화를 참조하세요.