การชนกัน

*เนื้อหานี้แปลโดยใช้ AI (เวอร์ชัน Beta) และอาจมีข้อผิดพลาด หากต้องการดูหน้านี้เป็นภาษาอังกฤษ ให้คลิกที่นี่

การชนกันเกิดขึ้นเมื่อวัตถุ 3 มิติสองชิ้นสัมผัสกันในโลก 3 มิติ สำหรับการจัดการการชนกันที่กำหนดเอง BasePart มีชุดของ เหตุการณ์การชนกัน และเทคนิค การกรองการชนกัน เพื่อให้คุณสามารถควบคุมว่าวัตถุทางกายภาพใดชนกับวัตถุอื่น

เหตุการณ์การชนกัน

เหตุการณ์การชนกัน เกิดขึ้น เมื่อ BaseParts สองชิ้นสัมผัสกันหรือหยุดสัมผัสกันในโลก 3 มิติ คุณสามารถตรวจจับการชนกันเหล่านี้ได้ผ่าน Touched และ TouchEnded ซึ่งเกิดขึ้นไม่ว่าจะมีค่า CanCollide ของแต่ละชิ้นส่วนเป็นอย่างไร เมื่อพิจารณาการจัดการการชนกันบนชิ้นส่วน ให้สังเกตสิ่งต่อไปนี้:

  • ค่า CanTouch ของชิ้นส่วนจะกำหนดว่ามันจะกระตุ้นเหตุการณ์การชนกันหรือไม่ หากตั้งค่าเป็น false จะไม่มีการเรียกใช้ Touched หรือ TouchEnded
  • ค่า CanCollide ของชิ้นส่วนจะมีผลต่อว่ามันจะ ชนกันทางกายภาพ กับชิ้นส่วนอื่นหรือไม่และทำให้เกิดแรงกระทำต่อพวกมัน แม้ว่าจะปิดการใช้งาน CanCollide สำหรับชิ้นส่วน คุณยังสามารถตรวจจับการสัมผัสและการไม่สัมผัสได้ผ่านเหตุการณ์ Touched และ TouchEnded
  • เหตุการณ์ Touched และ TouchEnded จะเกิดขึ้นเฉพาะจากการเคลื่อนไหว ทางกายภาพ ไม่ใช่จากการเปลี่ยนแปลง Position หรือ CFrame ที่ทำให้ชิ้นส่วนตัดกันหรือหยุดตัดกันกับชิ้นส่วนอื่น
  • คลาส Terrain ระดับสูงสุดสืบทอดมาจาก BasePart ดังนั้นคุณสามารถกำหนด กลุ่มการชนกัน ให้กับ Terrain เพื่อกำหนดว่าวัตถุ BaseParts อื่นจะชนกับ Terrain วอกเซลหรือไม่

Touched

เหตุการณ์ Touched จะเกิดขึ้นเมื่อ BasePart สัมผัสกับอีกชิ้นหนึ่ง หรือกับวอกเซล Terrain มันจะเกิดขึ้นเฉพาะจาก การจำลองทางกายภาพ และจะไม่เกิดขึ้นเมื่อค่า Position หรือ CFrame ของชิ้นส่วนถูกตั้งค่าอย่างชัดเจนเพื่อให้มันตัดกันกับชิ้นส่วนอื่นหรือวอกเซล

โค้ดตัวอย่างต่อไปนี้แสดงให้เห็นว่าเหตุการณ์ Touched สามารถเชื่อมต่อกับฟังก์ชัน onTouched() ที่กำหนดเองได้อย่างไร โปรดทราบว่าเหตุการณ์จะส่งอาร์กิวเมนต์ otherPart ไปยังฟังก์ชัน ซึ่งบ่งบอกถึงชิ้นส่วนอื่นที่เกี่ยวข้องในการชนกัน

Part Collision
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 มากเกินไป คุณสามารถใช้ระบบดีบาวน์ซ์ง่าย ๆ ที่บังคับใช้ "ระยะเวลาพัก" ผ่าน แอตทริบิวต์ ของอินสแตนซ์

Part Collision With Cooldown
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 ไปยังฟังก์ชัน ซึ่งบ่งบอกถึงชิ้นส่วนอื่นที่เกี่ยวข้อง

Non-Collision Detection
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

ในวิดีโอด้านบน วัตถุที่หมุนอยู่ในกลุ่มการชนกันที่แตกต่างกันทำให้พวกมันชนกับวัตถุที่มีสีอื่น แต่ไม่ชนกับวัตถุที่มีสีเดียวกัน

คุณสามารถตั้งค่ากลุ่มการชนกันได้อย่างง่ายดายผ่าน Collision Groups ของ Studio ซึ่งสามารถเข้าถึงได้ผ่านเมนู Window ⟩ 3D ของ Studio

ตัวแก้ไขทำงานใน List View ซึ่งเหมาะสำหรับ การจัดเรียง ไปทางด้านซ้ายหรือด้านขวาของ Studio หรือใน Table View ที่กว้างขึ้น ซึ่งเหมาะสำหรับการจัดเรียงไปทางด้านบนหรือล่าง

ตัวอย่าง List View ใน Collision Groups Editor

ลงทะเบียนกลุ่ม

ตัวแก้ไขรวมถึงกลุ่มการชนกัน Default หนึ่งกลุ่มซึ่งไม่สามารถเปลี่ยนชื่อหรือถูกลบได้ BaseParts ทั้งหมดจะอยู่ในกลุ่มเริ่มต้นนี้โดยอัตโนมัติ เว้นแต่จะถูกกำหนดให้กับกลุ่มอื่น ซึ่งหมายความว่าพวกมันจะชนกับวัตถุอื่นทั้งหมดในกลุ่ม Default

ในการสร้างกลุ่มการชนกันใหม่:

  1. คลิกปุ่ม Add Group ที่ด้านบนของแผงตัวแก้ไข ป้อนชื่อกลุ่มใหม่ และกด Enter กลุ่มใหม่จะปรากฏในทั้งสองคอลัมน์ของมุมมองรายการ หรือในทั้งคอลัมน์ซ้ายและแถวบนของมุมมองตาราง

    กลุ่มใหม่ที่เพิ่มใน Collision Groups Editor ใน List View
  2. ทำซ้ำกระบวนการหากจำเป็น โดยเลือกชื่อที่ไม่ซ้ำและมีความหมายสำหรับแต่ละกลุ่ม โปรดทราบว่าคุณสามารถเปลี่ยนชื่อกลุ่มในระหว่างการพัฒนาได้โดยการคลิกในฟิลด์ของมัน หรือโดยการเลือกมันและคลิกปุ่ม rename

    ปุ่มและฟิลด์ที่ระบุสำหรับการเปลี่ยนชื่อกลุ่มใน Collision Groups Editor

กำหนดการชนกันของกลุ่ม

ภายใต้การกำหนดค่าดีฟอลต์ วัตถุในทุกกลุ่มจะชนกันกับวัตถุในกลุ่มอื่น เพื่อป้องกันไม่ให้วัตถุในกลุ่มหนึ่งชนกับวัตถุในกลุ่มอื่น ให้ ยกเลิกการเลือก ช่องในแถว/คอลัมน์ที่เกี่ยวข้อง

ในตัวอย่างต่อไปนี้ วัตถุในกลุ่ม Cubes จะ ไม่ ชนกับวัตถุในกลุ่ม Doors

กลุ่มที่กำหนดใน List View ของ Collision Groups Editor

กำหนดวัตถุให้กับกลุ่ม

ในการกำหนดวัตถุให้กับกลุ่มที่คุณได้ ลงทะเบียน ผ่านตัวแก้ไข Studio:

  1. เลือก BaseParts หนึ่งชิ้นหรือมากกว่าที่มีคุณสมบัติเป็นส่วนหนึ่งของกลุ่มการชนกัน

  2. กำหนดให้พวกมันอยู่ในกลุ่มโดยการคลิกปุ่ม สำหรับแถวของมัน วัตถุสามารถอยู่ในกลุ่มการชนกันได้เพียงกลุ่มเดียวในแต่ละครั้ง ดังนั้นการวางพวกมันในกลุ่มใหม่จะทำให้พวกมันถูกลบออกจากกลุ่มปัจจุบัน

    ปุ่มบวกที่ระบุใน Collision Groups Editor สำหรับการเพิ่มชิ้นส่วนที่เลือกไปยังกลุ่ม

เมื่อกำหนดแล้ว กลุ่มใหม่จะสะท้อนอยู่ภายใต้ค่า CollisionGroup ของวัตถุ

กลุ่มการชนกันที่เลือกแสดงเป็นคุณสมบัติ CollisionGroup ของชิ้นส่วน

กลุ่มการชนกันที่เลือกใน Studio

เครื่องมือใน Studio ใช้ระบบการกรองการชนกันเพื่อตรวจสอบว่าวัตถุใดเป็นผู้สมัครสำหรับการเลือกเมื่อคลิกในมุมมอง 3 มิติ วัตถุที่มีกลุ่มการชนกันที่กำหนดซึ่ง ไม่ ชนกับ StudioSelectable จะถูกละเว้น

ตัวอย่างเช่น หากคุณมีจุดตรวจในเกมแข่งรถที่พื้นที่มีผลถูกกำหนดโดยชิ้นส่วนโปร่งใสขนาดใหญ่ คุณสามารถกำหนดให้พวกมันอยู่ในกลุ่มการชนกัน Checkpoints และจากนั้นทำให้กลุ่มนั้นไม่ชนกับ StudioSelectable เพื่อไม่ให้มันขวางทางเมื่อคุณกำลังแก้ไขรูปทรงพื้นฐานของแผนที่

กลุ่ม Checkpoints ที่กำหนดให้ไม่ชนกับกลุ่ม StudioSelectable

สำหรับโค้ดปลั๊กอิน แนะนำให้คุณกำหนด "StudioSelectable" เป็นตัวกรองกลุ่มการชนกันของ RaycastParams ของคุณเมื่อค้นหาชิ้นส่วนใต้เคอร์เซอร์ สิ่งนี้ช่วยให้ปลั๊กอินของคุณตรงตามกลไกการเลือกที่ผู้สร้างได้เรียนรู้ที่จะคาดหวังจากเครื่องมือใน Studio ที่สร้างขึ้น

Recommended Plugin Selection 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)

การกรองชิ้นส่วนต่อชิ้นส่วน

เพื่อป้องกันไม่ให้เกิดการชนกันระหว่างชิ้นส่วนเฉพาะสองชิ้นโดยไม่ต้องตั้งค่ากลุ่มการชนกัน collision groups เช่น ระหว่างล้อของรถยนต์และตัวถังของมัน ให้พิจารณาใช้ข้อจำกัด No Collision ข้อดีรวมถึง:

  • ไม่จำเป็นต้องมีกลุ่มการชนกันและ/หรือสคริปต์การกำหนดค่า ดังนั้นคุณจึงสามารถสร้างและแชร์โมเดลที่มีการกรองการชนกันที่กำหนดเองได้อย่างง่ายดาย
  • ชิ้นส่วนที่เชื่อมต่อกันจะไม่ชนกัน แต่ยังสามารถชนกับวัตถุอื่นได้

ปิดการชนกันของตัวละคร

ตัวละครของผู้เล่น Roblox จะชนกันโดยค่าเริ่มต้น สิ่งนี้อาจนำไปสู่การเล่นเกมที่น่าสนใจแต่ไม่ตั้งใจ เช่น ตัวละครกระโดดขึ้นไปบนกันและกันเพื่อไปยังพื้นที่เฉพาะ หากพฤติกรรมนี้ไม่ต้องการ คุณสามารถป้องกันได้ผ่าน Script ต่อไปนี้ใน ServerScriptService

Script - Disable Character Collisions
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 ทั้งหมดของโมเดลหลายชิ้นกับเหตุการณ์การชนกันและติดตามจำนวนการชนกันทั้งหมดกับชิ้นส่วนอื่น

Model Collision
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

การชนกันของ Mesh และ Solid Model

MeshPart และ PartOperation (ชิ้นส่วนที่เชื่อมต่อกันโดย การสร้างโมเดลที่เป็นของแข็ง) เป็นซับคลาสของ BasePart ดังนั้น Mesh และชิ้นส่วนที่สร้างโมเดลที่เป็นของแข็งจึงสืบทอด เหตุการณ์การชนกัน และตัวเลือก การกรองการชนกัน เช่นเดียวกับชิ้นส่วนปกติ อย่างไรก็ตาม เนื่องจาก Mesh และชิ้นส่วนที่สร้างโมเดลที่เป็นของแข็งมักมีรูปทรงเรขาคณิตที่ซับซ้อนมากขึ้น พวกมันจึงมีคุณสมบัติ CollisionFidelity ที่โดดเด่นซึ่งกำหนดว่าขอบเขตทางกายภาพจะตรงกับการแสดงผลทางสายตาอย่างไรสำหรับการจัดการการชนกัน

คุณสมบัติ CollisionFidelity มีตัวเลือกดังต่อไปนี้ โดยเรียงตามความแม่นยำและผลกระทบต่อประสิทธิภาพจากต่ำสุดไปสูงสุด:

  • Box — สร้างกล่องการชนกันที่เป็นขอบเขต เหมาะสำหรับวัตถุขนาดเล็กหรือไม่โต้ตอบ
  • Hull — สร้างฮัลล์นูน เหมาะสำหรับวัตถุที่มีรอยบุ๋มหรือโพรงน้อย
  • Default — สร้างรูปร่างการชนกันโดยประมาณที่รองรับความโค้ง เหมาะสำหรับวัตถุที่ซับซ้อนที่มีความต้องการการโต้ตอบที่มีรายละเอียดปานกลาง
  • PreciseConvexDecomposition — เสนอความแม่นยำสูงสุดแต่ยังไม่ใช่การแสดงผล 1:1 ของการแสดงผล ตัวเลือกนี้มีค่าใช้จ่ายด้านประสิทธิภาพที่แพงที่สุดและใช้เวลานานกว่าในการคำนวณของเอนจิน
Mesh ดั้งเดิมของหอคอยปราสาท

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับผลกระทบด้านประสิทธิภาพของตัวเลือกความแม่นยำของการชนกันและวิธีลดผลกระทบเหล่านั้น โปรดดูที่ การเพิ่มประสิทธิภาพ

©2026 Roblox Corporation. Roblox, โลโก้ Roblox และ Powering Imagination เป็นส่วนหนึ่งของเครื่องหมายการค้าที่จดทะเบียน และไม่ได้จดทะเบียนของเราในสหรัฐฯ และประเทศอื่นๆ