ل支持 الآليات الفيزيائية المعقدة مع السعي أيضًا لتحقيق تجربة سلسة واستجابتها للاعبين، يستخدم محرك الفيزياء في 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
-- Get the player from the character
local player = Players:GetPlayerFromCharacter(humanoid.Parent)
if player then
vehicleSeat:SetNetworkOwner(player)
end
else
-- Reset ownership when seat is unoccupied
vehicleSeat:SetNetworkOwnershipAuto()
end
end
end)
تصور الملكية
لمساعدة في تصحيح أخطاء ملكية الشبكة، يمكن لـ Studio أن تعرض خطوط ملونة حول كائنات عند اختبار اللعب.
| لون الخط | الوصف | |
|---|---|---|
| (أخضر) | يملك عميلك الجزء ويقوم بمحاكاته. | |
| (أحمر) | الجزء ضمن "منطقة عازلة" حيث يقوم عميلك بمحاكاته ولكنه لا يزال مملوكًا لشيء آخر. قد يحصل عميلك على الملكية بعد ذلك، أو قد يتم رفضها. | |
| (أبيض/رمادي) | يمتلك الخادم أو عميل آخر الجزء عبر ملكية الشبكة التلقائية أو من خلال تعيين واضح عبر part:SetNetworkOwner(). | |
| (أسود) | الجزء ليس مملوكًا للخادم أو العميل. لن يتم تطبيق الفيزياء على هذا الجزء. | |
لتمكين تصور ملكية الشبكة:
انقر على زر خيارات التصور في الزاوية العليا اليمنى من نافذة العرض ثلاثية الأبعاد.

في قائمة المنسدلة، قم بتبديل مالكي الشبكة.
مخاوف أمنية
لا يمكن لـ Roblox التحقق من حسابات الفيزياء عندما يمتلك عميل ملكية BasePart. يمكن للعملاء استغلال ذلك وإرسال بيانات سيئة إلى الخادم، مثل نقل BasePart ، وجعلها تمر عبر الجدران أو تطير حولها.
بالإضافة إلى ذلك، ترتبط أحداث BasePart.Touched بملكية الشبكة، مما يعني أن العميل يمكنه تشغيل أحداث Touched على BasePart الذي يمتلكه ويرسلها إلى الخادم، حتى لو لم ير الخادم أنه يلمس أي شيء. على سبيل المثال، يمكن لعميل جعل سيف يسبب الضرر للاعب آخر عبر الخريطة عن طريق إطلاق الحدث عبر حقن السكربت، لذا من المهم التحقق من صحة مثل هذه الأحداث التي يطلقها العملاء.
انظر إلى تكتيكات الأمان وتقليل الاحتيال للحصول على تكتيكات أمنية مفصلة وتكتيكات تقليل الاحتيال لألعاب Roblox.