الاصطدامات

*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 .. " collided with " .. otherPart.Name)
end
part.Touched:Connect(onTouched)

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

جزء الاصطدام مع فترة استراحة

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 .. " collided with " .. otherPart.Name)
part:SetAttribute("Touched", true) -- تعيين الخاصية إلى true
task.wait(COOLDOWN_TIME) -- الانتظار لمدة فترة الاستراحة
part:SetAttribute("Touched", false) -- إعادة تعيين الخاصية
end
end
part.Touched:Connect(onTouched)

TouchEnded

يحدث حدث 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 .. " is no longer touching " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

تستخدم الأدوات في الاستوديو نظام تصفية الاصطدام لتحديد أي الأشياء مرشحة للاختيار عند النقر في عرض 3D. سيتم تجاهل الأشياء التي لا تصطدم بمجموعة StudioSelectable المخصصة لها.

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

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

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

تحديد الشعاع الموصى به للمكونات الإضافية

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. تتضمن المزايا:

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

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

تتصادم شخصيات اللاعبين في روبلوكس مع بعضها بشكل افتراضي. يمكن أن يؤدي هذا إلى طريقة لعب ممتعة ولكن غير مقصودة، مثل الشخصيات التي تقفز فوق بعضها للوصول إلى مناطق معينة. إذا كانت هذه السلوكيات غير مرغوبة، يمكنك منعها من خلال البرنامج النصي التالي 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, "intersected with", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- تجاهل حالات النموذج التي تتوقف عن التداخل مع نفسها
if otherPart:IsDescendantOf(model) then return end
-- تقليل عدد أجزاء النموذج المتلامسة
numTouchingParts -= 1
print(model.Name, "un-intersected from", otherPart.Name, "| Model parts touching:", 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 وشعار "توسيع حدود المخيلة"، من ضمن علاماتنا التجارية المسجّلة وغير المسجّلة في الولايات المتحدة وبلدان أخرى.