Một va chạm xảy ra khi hai đối tượng 3D tiếp xúc trong thế giới 3D.Đối với xử lý va chạm tùy chỉnh, BasePart có một bộ các sự kiện va chạm và kỹ thuật lọc va chạm , vì vậy bạn có thể kiểm soát các tập hợp vật lý nào va chạm với nhau.
Sự kiện va chạm
Sự va chạm sự kiện xảy ra khi hai BaseParts tiếp xúc hoặc dừng tiếp xúc trong thế giới 3D.Bạn có thể phát hiện những va chạm này thông qua sự kiện và xảy ra bất kể giá trị tính năng của bất kỳ phần nào trong số đó.Khi xem xét xử lý va chạm trên các bộ phận, hãy lưu ý điều theo dõi:
- Thuộc tính của một phần CanTouch xác định xem nó có kích hoạt sự kiện va chạm hay không. Nếu được đặt thành false, không có Touched hoặc TouchEnded sẽ bắn.
- Tính chất của một phần CanCollide ảnh hưởng đến việc nó sẽ vật lý va chạm với các phần khác và gây ra lực để tác động lên chúng.Ngay cả khi CanCollide bị vô hiệu hóa cho một phần, bạn có thể phát hiện chạm và không chạm thông qua Touched và TouchEnded sự kiện.
- Các sự kiện Touched và TouchEnded chỉ bắt lửa khi là kết quả của chuyển động vật lý không từ một thay đổi Position hoặc CFrame gây cho một phần va chạm hoặc dừng va chạm với một phần khác.
Chạm vào
Sự kiện Touched xảy ra khi một BasePart có tiếp xúc với một khác, hoặc với một voxel Địa hình .Nó chỉ bắn ra là kết quả của mô phỏng vật lý và sẽ không bắn khi phần Position hoặc CFrame được đặt rõ ràng như vậy để chúng chồng lấp với một phần khác hoặc voxel khác
Mẫu mã code sau đây cho thấy cách sự kiện Touched có thể được kết nối với chức năng tùy chỉnh onTouched() .Lưu ý rằng sự kiện gửi argument otherPart đến chức năng, chỉ ra phần khác tham gia vào va chạm.
Va chạm phần
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)
Lưu ý rằng sự kiện Touched có thể bắn nhiều lần trong chuỗi thành công nhanh chóng dựa trên những va chạm vật lý tinh tế, chẳng hạn như khi một vật thể di chuyển "định cư" vào một vị trí nghỉ ngơi hoặc khi một va chạm liên quan đến một mô hình nhiều phần .Để tránh kích hoạt nhiều sự kiện hơn cần thiết, bạn có thể triển khai một hệ thống giảm thời gian chậm chạp đơn giản bằng cách áp dụng một thuộc tính "thời gian chờ" thông qua một ví dụ .
Va chạm phần với thời gian chờ
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) -- Đặt thuộc tính thành true
task.wait(COOLDOWN_TIME) -- Chờ thời gian chờ đợi
part:SetAttribute("Touched", false) -- Đặt lại thuộc tính
end
end
part.Touched:Connect(onTouched)
Chạm kết thúc
Sự kiện TouchEnded xảy ra khi toàn bộ giới hạn va chạm của một BasePart rời khỏi giới hạn của một BasePart khác hoặc một voxel Địa hình đã được lấp đầy.Nó chỉ bắn ra là kết quả của mô phỏng vật lý và sẽ không bắn khi phần Position hoặc CFrame được đặt rõ ràng như vậy mà nó dừng lại chồng lấp với một phần khác hoặc voxel khác
Mẫu mã code sau đây cho thấy cách sự kiện TouchEnded có thể được kết nối với chức năng tùy chỉnh onTouchEnded() .Giống như Touched , sự kiện gửi otherPart đối số cho chức năng, chỉ ra phần khác liên quan.
Không phát hiện va chạm
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)
Lọc va chạm
Lọc va chạm định nghĩa xác định các bộ phận vật lý nào va chạm với nhau.Bạn có thể thiết lập lọc cho nhiều đối tượng thông qua nhóm va chạm hoặc bạn có thể kiểm soát va chạm trên cơ sở phần tới phần với NoCollisionConstraint các thực thể.
Nhóm va chạm
Va chạm nhóm cho phép bạn gán BaseParts cho các nhóm dành riêng và xác định xem có va chạm với những người khác trong các nhóm khác hay không.Các bộ phận trong các nhóm không va chạm lẫn nhau hoàn toàn, ngay cả khi cả hai bộ phận có chỉ số CanCollide tài sản được đặt thành true .
Bạn có thể dễ dàng thiết lập các nhóm va chạm thông qua Studio's Trình soạn thảo Nhóm va chạm , có thể truy cập bằng cách nhấp vào nút Nhóm va chạm trong tab Mô hình của công cụ.

Chức năng biên tập hoạt động trong View Danh sách mà ưu tiên ghép nối về bên trái hoặc bên phải của Studio, hoặc trong View Bảng trống rộng hơn, mà ưu tiên ghép nối về phía trên hoặc dưới.

Đăng ký nhóm
Trình soạn thảo bao gồm một nhóm va chạm mặc định Mặc định không thể được đổi tên hoặc xóa.Tất cả BaseParts tự động thuộc nhóm mặc định này trừ khi được gán cho nhóm khác, có nghĩa là chúng sẽ va chạm với tất cả các đối tượng khác trong nhóm Mặc định .
Để tạo một nhóm va chạm mới:
Nhấp vào nút Thêm nhóm ở phía trên cùng của bảng điều khiển biên tập, nhập tên nhóm mới và nhấn Enter .Nhóm mới xuất hiện trong cả hai cột của bản xem danh sách hoặc trong cả hai cột bên trái và hàng trên cùng của bản xem bảng.
Lặp lại quá trình nếu cần thiết, chọn một tên duy nhất và mô tả cho mỗi nhóm.Lưu ý rằng bạn có thể thay đổi tên của một nhóm trong quá trình phát triển bằng cách nhấp vào trường của nó, hoặc bằng cách chọn nó và nhấp vào nút thay đổi tên .
Tùy chỉnh va chạm nhóm
Trong cấu hình mặc định, các đối tượng trong tất cả các nhóm va chạm với nhau.Để ngăn chặn các đối tượng trong một nhóm va chạm với các đối tượng trong nhóm khác, hãy bỏ chọn hộp trong dòng/cột tương ứng.
Trong ví dụ sau, các đối tượng trong nhóm Hộp sẽ không va chạm với các đối tượng trong nhóm Cửa .

Gán đối tượng cho nhóm
Để gán đối tượng cho nhóm bạn đã đăng ký thông qua trình soạn thảo Studio:
Chọn một hoặc nhiều BaseParts đủ điều kiện làm phần của một nhóm va chạm.
Gán chúng cho nhóm bằng cách nhấp vào nút ⊕ cho hàng của nó.Các đối tượng chỉ có thể thuộc về một nhóm va chạm duy nhất tại một thời điểm, do đó đặt chúng trong một nhóm mới sẽ loại bỏ chúng khỏi nhóm hiện tại của chúng.
Một khi được gán, nhóm mới được phản ánh dưới tính năng CollisionGroup của đối tượng.

Nhóm va chạm có thể chọn nhóm
Các công cụ trong Studio sử dụng hệ thống lọc va chạm để xác định các đối tượng là ứng cử viên để lựa chọn khi nhấp vào cửa sổ xem 3D.Các đối tượng có nhóm va chạm được gán có không va chạm với StudioSelectable sẽ bị bỏ qua.
Ví dụ, nếu bạn có điểm kiểm tra trong trải nghiệm đua xe có các khu vực hiệu quả được xác định bởi các bộ phận trong suốt lớn, bạn có thể gán chúng vào một nhóm va chạm điểm kiểm tra có hiệu lực và sau đó làm cho nhóm đó không va chạm với StudioSelectable để chúng không bị cản trở khi bạn đang chỉnh sửa địa hình bản đồ cơ sở.

Đối với mã plugin, được khuyến nghị rằng bạn nên gán "StudioSelectable" như bộ lọc nhóm va chạm của phần RaycastParams khi tìm các bộ phận dưới con trỏ.Điều này cho phép các plugin phù hợp với cơ chế lựa chọn mà các nhà sáng tạo đã học được để mong đợi từ các công cụ Studio tích hợp.
Raycast lựa chọn plugin được đề xuất
local UserInputService = game:GetService("UserInputService")local Workspace = game:GetService("Workspace")local raycastParams = RaycastParams.new()raycastParams.CollisionGroup = "StudioSelectable" -- Để tuân theo tiêu chuẩnraycastParams.BruteForceAllSlow = true -- Để các bộ phận với CanQuery của "false" có thể được chọnlocal mouseLocation = UserInputService:GetMouseLocation()local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)
Lọc theo phần đến phần
Để ngăn chặn va chạm giữa hai phần cụ thể mà không cài đặt nhóm va chạm, chẳng hạn như giữa bánh xe của một chiếc xe và khung của nó, hãy xem xét giới hạn Không va chạm.Các lợi thế bao gồm:
- Nhóm va chạm và/hoặc kịch bản cấu hình không cần thiết, vì vậy bạn có thể dễ dàng tạo và chia sẻ mô hình với bộ lọc va chạm tùy chỉnh.
- Các bộ phận kết nối sẽ không va chạm với nhau, nhưng chúng vẫn có thể va chạm với các đối tượng khác.
Vô hiệu hóa va chạm nhân vật
Nhân vật người chơi Roblox va chạm với nhau theo mặc định.Điều này có thể dẫn đến trải nghiệm trò chơithú vị nhưng không được ý định, chẳng hạn như các nhân vật nhảy lên nhau để tiếp cận các khu vực cụ thể.Nếu hành vi này không mong muốn, bạn có thể ngăn chặn nó thông qua Script sau trong ServerScriptService .
Script - Vô hiệu hóa xung đột nhân vật
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
local CollisionGroupName = "Characters"
PhysicsService:RegisterCollisionGroup(CollisionGroupName)
PhysicsService:CollisionGroupSetCollidable(CollisionGroupName, CollisionGroupName, false)
local function setCollisionGroup(model)
-- Áp dụng nhóm va chạm cho tất cả các bộ phận hiện có trong mô hình
for _, descendant in model:GetDescendants() do
if descendant:IsA("BasePart") then
descendant.CollisionGroup = CollisionGroupName
end
end
end
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
setCollisionGroup(character)
end)
-- Nếu người chơi đã có một nhân vật, áp dụng nhóm va chạm ngay lập tức
if player.Character then
setCollisionGroup(player.Character)
end
end)
Va chạm mô hình
Model các đối tượng là thùng chứa cho các bộ phận thay vì kế thừa từ BasePart , vì vậy chúng không thể kết nối trực tiếp với BasePart.Touched hoặc BasePart.TouchEnded sự kiện.Để xác định xem mô hình có kích hoạt sự kiện va chạm hay không, bạn cần lặp qua các con của nó và kết nối các chức năng tùy chỉnh onTouched() và onTouchEnded() với mỗi con cái BasePart .
Ví dụ mã sau đây kết nối tất cả BaseParts của một mô hình nhiều phần với sự kiện va chạm và theo dõi tổng số va chạm với các phần khác.
Va chạm mô hình
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Bỏ qua các ví dụ của mô hình va chạm với chính nó
if otherPart:IsDescendantOf(model) then return end
-- Tăng số lượng phần mô hình tiếp xúc
numTouchingParts += 1
print(model.Name, "intersected with", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Bỏ các ví dụ của mô hình không va chạm với chính nó
if otherPart:IsDescendantOf(model) then return end
-- Giảm số lượng phần mô hình tiếp xúc
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
Va chạm giữa mạng lưới và mô hình rắn chắc
MeshPart và PartOperation (các bộ phận được kết nối bởi mô hình solid ) là các phân loại thứ cấp của BasePart , vì vậy các khối và các bộ phận được mô hình hóa solid thừa hưởng các tùy chọn sự kiện va chạm và lọc va chạm giống như các bộ phận thông thường.Tuy nhiên, vì các khối lượng và phần mô hình rắn thường có các hình học phức tạp hơn, chúng có một tính năng đặc biệt CollisionFidelity để xác định cách chính xác giới hạn vật lý khớp với đại diện hình ảnh cho xử lý va chạm.
Thuộc tính CollisionFidelity có các tùy chọn sau, theo thứ tự chính xác và tác động đến hiệu suất từ thấp nhất đến cao nhất:
- Hộp — Tạo một hộp va chạm giới hạn, lý tưởng cho các đối tượng nhỏ hoặc không tương tác.
- Hull — Tạo một hình trụ tròn, phù hợp với các đối tượng có các lõm hay hố nhỏ hơn.
- Mặc định — Sản xuất một hình dạng va chạm khái niệm gần giống hỗ trợ sự lõm, thích hợp cho các đối tượng phức tạp có nhu cầu tương tác bán thủ công.
- Phân tích bề ngoài chính xác — Cung cấp độ chính xác cao nhất nhưng vẫn không phải là đại diện 1:1 của hình ảnh.Tùy chọn này có chi phí hiệu suất đắt nhất và mất nhiều thời gian hơn để động cơ tính toán.

Để biết thêm thông tin về tác động đến hiệu suất của các tùy chọn chính xác va chạm và cách giảm thiểu chúng, xem tối ưu hóa hiệu suất.