التصادمات

*This content is translated using AI (Beta) and may contain errors. To view this page in English, click here.

يحدث التصادم عندما تتلامس كائنان ثلاثي الأبعاد داخل العالم ثلاثي الأبعاد. من أجل معالجة التصادمات المخصصة، تحتوي BasePart على مجموعة من أحداث التصادم وتقنيات تصفية التصادم، بحيث يمكنك التحكم في الكيانات الفيزيائية التي تتصادم مع الأخرى.

أحداث التصادم

تحدث أحداث التصادم عندما تلمس كائنان من BaseParts أو تتوقفان عن اللمس في العالم ثلاثي الأبعاد. يمكنك اكتشاف هذه التصادمات من خلال أحداث Touched و TouchEnded التي تحدث بغض النظر عن قيمة خاصية CanCollide لأي جزء. عند النظر في معالجة التصادم على الأجزاء، لاحظ ما يلي:

  • تحدد خاصية CanTouch لجزء ما ما إذا كان سيؤدي إلى أحداث التصادم. إذا تم تعيينها إلى false، فلن يتم تشغيل أي من Touched أو TouchEnded.
  • تؤثر خاصية CanCollide لجزء ما على ما إذا كان سيتصادم فيزيائيًا مع أجزاء أخرى ويتسبب في تأثيرات عليها. حتى إذا تم تعطيل CanCollide لجزء ما، يمكنك اكتشاف اللمس وعدم اللمس من خلال أحداث Touched و TouchEnded.
  • تحدث أحداث Touched و TouchEnded فقط نتيجة للحركة الفيزيائية، وليس من تغييرات Position أو CFrame التي تتسبب في تقاطع جزء مع جزء آخر أو توقفه عن التقاطع.
  • ترث فئة Terrain العليا من BasePart، لذا يمكنك تعيين مجموعة تصادم لـ Terrain لتحديد ما إذا كانت أجزاء BaseParts الأخرى تتصادم مع الفوكسلات Terrain.

تم اللمس

تحدث حدث Touched عندما يتلامس BasePart مع آخر، أو مع فوكسل Terrain. يحدث فقط نتيجة لـ محاكاة فيزيائية ولن يحدث عندما يتم تعيين Position أو CFrame بشكل صريح بحيث يتقاطع مع جزء آخر أو فوكسل.

تظهر نمط الكود التالي كيف يمكن ربط حدث Touched بدالة مخصصة onTouched(). لاحظ أن الحدث يرسل الوسيطة otherPart إلى الدالة، مما يشير إلى الجزء الآخر المعني في التصادم.

تصادم الجزء
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouched(otherPart)
print(part.Name .. " تصادم مع " .. otherPart.Name)
end
part.Touched:Connect(onTouched)

لاحظ أن حدث Touched يمكن أن يحدث عدة مرات في تسلسل سريع بناءً على تصادمات فيزيائية دقيقة، مثل عندما "يستقر" كائن متحرك في وضع راحة أو عندما يتضمن التصادم نموذج متعدد الأجزاء. لتجنب تشغيل المزيد من أحداث Touched أكثر من اللازم، يمكنك تنفيذ نظام بسيط للحد من التكرار الذي يفرض فترة "تبريد" من خلال خاصية attribute.

تصادم الجزء مع فترة تبريد
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local COOLDOWN_TIME = 1
local function onTouched(otherPart)
if not part:GetAttribute("Touched") then
print(part.Name .. " تصادم مع " .. otherPart.Name)
part:SetAttribute("Touched", true) -- تعيين الخاصية إلى true
task.wait(COOLDOWN_TIME) -- الانتظار لفترة التبريد
part:SetAttribute("Touched", false) -- إعادة تعيين الخاصية
end
end
part.Touched:Connect(onTouched)

تم إنهاء اللمس

يحدث حدث TouchEnded عندما تخرج الحدود الكاملة للتصادم لـ BasePart من حدود جزء آخر من BasePart أو فوكسل Terrain المملوء. يحدث فقط نتيجة لـ محاكاة فيزيائية ولن يحدث عندما يتم تعيين Position أو CFrame بشكل صريح بحيث يتوقف عن التقاطع مع جزء آخر أو فوكسل.

تظهر نمط الكود التالي كيف يمكن ربط حدث TouchEnded بدالة مخصصة onTouchEnded(). مثل Touched، يرسل الحدث الوسيطة otherPart إلى الدالة، مما يشير إلى الجزء الآخر المعني.

كشف عدم التصادم
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " لم يعد يلمس " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)

تصفية التصادم

تحدد تصفية التصادم أي الأجزاء الفيزيائية تتصادم مع الأخرى. يمكنك تكوين التصفية للعديد من الكائنات من خلال مجموعات التصادم أو يمكنك التحكم في التصادمات على أساس جزء إلى جزء باستخدام مثيلات NoCollisionConstraint.

مجموعات التصادم

تتيح لك مجموعات التصادم تعيين BaseParts إلى مجموعات مخصصة وتحديد ما إذا كانت تتصادم مع تلك الموجودة في مجموعات أخرى أم لا. تمر الأجزاء داخل المجموعات غير المتصادمة عبر بعضها البعض تمامًا، حتى لو كانت كلا الجزئين لهما خاصية CanCollide مضبوطة على true.

في الفيديو أعلاه، الأشياء الدوارة في مجموعات تصادم مختلفة بحيث تتصادم مع أشياء بلون آخر ولكن لا تتصادم مع أشياء بلونها الخاص

يمكنك إعداد مجموعات التصادم بسهولة من خلال محرر مجموعات التصادم في الاستوديو، والذي يمكن الوصول إليه من خلال قائمة نافذة ⟩ 3D في الاستوديو.

يعمل المحرر في وضع عرض القائمة الذي يفضل التثبيت على الجانب الأيسر أو الأيمن من الاستوديو، أو في وضع عرض الجدول الأوسع، الذي يفضل التثبيت في الأعلى أو الأسفل.

مثال عرض القائمة في محرر مجموعات التصادم

تسجيل المجموعات

يتضمن المحرر مجموعة افتراضية واحدة لا يمكن إعادة تسميتها أو حذفها. جميع BaseParts تنتمي تلقائيًا إلى هذه المجموعة الافتراضية ما لم يتم تعيينها إلى مجموعة أخرى، مما يعني أنها ستتصادم مع جميع الكائنات الأخرى في مجموعة افتراضية.

لإنشاء مجموعة تصادم جديدة:

  1. انقر على زر إضافة مجموعة في أعلى لوحة المحرر، أدخل اسم مجموعة جديدة، واضغط Enter. ستظهر المجموعة الجديدة في كلا العمودين في عرض القائمة، أو في كلا العمود الأيسر والصف العلوي في عرض الجدول.

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

    زر وحقل محدد لإعادة تسمية مجموعة في محرر مجموعات التصادم

تكوين تصادم المجموعات

تحت التكوين الافتراضي، تتصادم الكائنات في جميع المجموعات مع بعضها البعض. لمنع الكائنات في مجموعة واحدة من التصادم مع الكائنات في مجموعة أخرى، قم بإلغاء تحديد المربع في الصف/العمود المعني.

في المثال التالي، لن تتصادم الكائنات في مجموعة Cubes مع الكائنات في مجموعة Doors.

مجموعة تم تكوينها في عرض القائمة لمحرر مجموعات التصادم

تعيين الكائنات إلى المجموعات

لتعيين الكائنات إلى المجموعات التي قمت بتسجيلها من خلال محرر الاستوديو:

  1. حدد واحدًا أو أكثر من BaseParts التي تتأهل كجزء من مجموعة تصادم.

  2. قم بتعيينها إلى المجموعة من خلال النقر على زر لصفها. يمكن أن تنتمي الكائنات إلى مجموعة تصادم واحدة فقط في كل مرة، لذا فإن وضعها في مجموعة جديدة يزيلها من مجموعتها الحالية.

    زر زائد محدد في محرر مجموعات التصادم لإضافة الأجزاء المحددة إلى مجموعة

بمجرد تعيينها، يتم عكس المجموعة الجديدة تحت خاصية CollisionGroup للكائن.

المجموعة المختارة محددة كخاصية CollisionGroup للجزء

مجموعة التصادم القابلة للاختيار في الاستوديو

تستخدم الأدوات في الاستوديو نظام تصفية التصادم لتحديد أي الكائنات هي مرشحة للاختيار عند النقر في نافذة العرض ثلاثي الأبعاد. سيتم تجاهل الكائنات التي لا تتصادم مجموعتها المعينة مع StudioSelectable.

على سبيل المثال، إذا كان لديك نقاط تفتيش في لعبة سباق يتم تعريف مناطقها الفعالة بواسطة أجزاء شفافة كبيرة، يمكنك تعيينها إلى مجموعة تصادم Checkpoints ثم جعل تلك المجموعة غير قابلة للتصادم مع StudioSelectable حتى لا تعيق عند تحرير هندسة الخريطة الأساسية.

مجموعة نقاط التفتيش تم تكوينها لتكون غير قابلة للتصادم مع مجموعة StudioSelectable

بالنسبة لرمز المكون الإضافي، يُوصى بتعيين "StudioSelectable" كمرشح مجموعة التصادم لـ RaycastParams عند العثور على الأجزاء تحت المؤشر. هذا يسمح لمكوناتك الإضافية بمطابقة آليات الاختيار التي تعلمها المبدعون أن يتوقعوها من أدوات الاستوديو المدمجة.

توصية اختيار المكون الإضافي Raycast
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- لمتابعة التقليد
raycastParams.BruteForceAllSlow = true -- حتى يمكن اختيار الأجزاء التي لديها CanQuery من "false"
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)

تصفية جزء إلى جزء

لمنع التصادمات بين جزئين محددين دون إعداد مجموعات التصادم، مثل بين عجلة مركبة وهيكلها، ضع في اعتبارك استخدام قيد No Collision. تشمل المزايا:

  • لا تتطلب مجموعات التصادم و/أو نصوص التكوين، لذا يمكنك بسهولة إنشاء ومشاركة نماذج مع تصفية تصادم مخصصة.
  • لن تتصادم الأجزاء المتصلة مع بعضها، لكنها لا تزال يمكن أن تتصادم مع كائنات أخرى.

تعطيل تصادمات الشخصيات

تتصادم شخصيات لاعبي Roblox مع بعضها بشكل افتراضي. يمكن أن يؤدي ذلك إلى أسلوب لعب مثير ولكن غير مقصود، مثل قفز الشخصيات فوق بعضها للوصول إلى مناطق معينة. إذا كانت هذه السلوكيات غير مرغوب فيها، يمكنك منعها من خلال البرنامج النصي التالي Script في ServerScriptService.

برنامج نصي - تعطيل تصادمات الشخصيات
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:CollisionGroupSetCollidable("Characters", "Characters", false)
local function onDescendantAdded(descendant)
-- تعيين مجموعة التصادم لأي جزء تابع
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Characters"
end
end
local function onCharacterAdded(character)
-- معالجة التوابع الموجودة والجديدة لإعداد الفيزياء
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- اكتشاف متى يتم إضافة شخصية اللاعب
player.CharacterAdded:Connect(onCharacterAdded)
end)

تصادمات النماذج

تعتبر كائنات Model حاويات للأجزاء بدلاً من أن ترث من BasePart، لذا لا يمكنها الاتصال مباشرة بأحداث BasePart.Touched أو BasePart.TouchEnded. لتحديد ما إذا كان نموذج ما يؤدي إلى أحداث التصادم، تحتاج إلى التكرار عبر أطفاله وربط دوال onTouched() و onTouchEnded() المخصصة بكل جزء BasePart.

تظهر عينة الكود التالية كيف يمكن ربط جميع BaseParts لنموذج متعدد الأجزاء بأحداث التصادم وتتبع العدد الإجمالي للتصادمات مع أجزاء أخرى.

تصادم النموذج
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- تجاهل حالات تقاطع النموذج مع نفسه
if otherPart:IsDescendantOf(model) then return end
-- زيادة عدد الأجزاء المتلامسة للنموذج
numTouchingParts += 1
print(model.Name, "تقاطع مع", otherPart.Name, "| أجزاء النموذج المتلامسة:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- تجاهل حالات عدم تقاطع النموذج مع نفسه
if otherPart:IsDescendantOf(model) then return end
-- تقليل عدد الأجزاء المتلامسة للنموذج
numTouchingParts -= 1
print(model.Name, "لم يعد متقاطعًا مع", otherPart.Name, "| أجزاء النموذج المتلامسة:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
end

تصادمات الشبكة والنماذج الصلبة

تعتبر MeshPart و PartOperation (الأجزاء المتصلة بواسطة النمذجة الصلبة) فئات فرعية من BasePart، لذا فإن الأجزاء الشبكية والنمذجة الصلبة ترث نفس أحداث التصادم و تصفية التصادم مثل الأجزاء العادية. ومع ذلك، نظرًا لأن الأجزاء الشبكية والنمذجة الصلبة عادةً ما تحتوي على هندسة أكثر تعقيدًا، فإن لديها خاصية مميزة CollisionFidelity التي تحدد مدى دقة محاذاة الحدود الفيزيائية مع التمثيل البصري لمعالجة التصادم.

تمتلك خاصية CollisionFidelity الخيارات التالية، بترتيب الدقة وتأثير الأداء من الأدنى إلى الأعلى:

  • صندوق — ينشئ صندوق تصادم محيط، مثالي للأشياء الصغيرة أو غير التفاعلية.
  • قذيفة — يولد قذيفة محدبة، مناسبة للأشياء ذات التجاويف أو الفجوات الأقل وضوحًا.
  • افتراضي — ينتج شكل تصادم تقريبي يدعم الانحناء، مناسب للأشياء المعقدة ذات احتياجات التفاعل شبه المفصلة.
  • تحلل دقيق محدب — يقدم أعلى دقة ولكن لا يزال ليس تمثيلًا 1:1 للتمثيل البصري. هذه الخيار له أعلى تكلفة أداء ويستغرق وقتًا أطول للحساب بواسطة المحرك.
الشبكة الأصلية لبرج قلعة

لمزيد من المعلومات حول تأثير الأداء لخيارات دقة التصادم وكيفية التخفيف منها، انظر تحسين الأداء.

©2026 شركة Roblox Corporation. تُعد منصّة Roblox، وشعار Roblox وشعار "توسيع حدود المخيلة"، من ضمن علاماتنا التجارية المسجّلة وغير المسجّلة في الولايات المتحدة وبلدان أخرى.