Va chạm

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

Một va chạm xảy ra khi hai đối tượng 3D tiếp xúc trong thế giới 3D. Để xử lý va chạm tùy chỉnh, BasePart có một bộ sự kiện va chạm và các kỹ thuật lọc va chạm, vì vậy bạn có thể kiểm soát các lắp ráp vật lý nào va chạm với nhau.

Sự kiện va chạm

Sự kiện va chạm sự kiện xảy ra khi hai BaseParts chạm vào nhau hoặc ngừng chạm trong thế giới 3D. Bạn có thể phát hiện các va chạm này thông qua các sự kiện TouchedTouchEnded, xảy ra bất kể giá trị thuộc tính CanCollide của mỗi phần. Khi xem xét việc xử lý va chạm trên các phần, hãy lưu ý điều sau:

  • Thuộc tính CanTouch của một phần xác định liệu nó có kích hoạt các sự kiện va chạm hay không. Nếu được đặt thành false, cả TouchedTouchEnded đều sẽ không được kích hoạt.
  • Thuộc tính CanCollide của một phần ảnh hưởng đến việc nó có va chạm vật lý với các phần khác hay không 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 vẫn có thể phát hiện chạm và không chạm thông qua các sự kiện TouchedTouchEnded.
  • Các sự kiện TouchedTouchEnded chỉ được kích hoạt do sự chuyển động vật lý, không phải từ các thay đổi Position hoặc CFrame gây ra cho một phần giao thoa hoặc ngừng giao thoa với một phần khác.
  • Lớp cấp cao Terrain kế thừa từ BasePart, vì vậy bạn có thể gán một nhóm va chạm cho Terrain để xác định liệu các BaseParts khác có va chạm với các voxel Địa hình hay không.

Touched

Sự kiện Touched được kích hoạt khi một BasePart tiếp xúc với một phần khác, hoặc với một voxel Địa hình. Nó chỉ được kích hoạt do mô phỏng vật lý và sẽ không được kích hoạt khi thuộc tính Position hoặc CFrame của phần được đặt một cách rõ ràng đến mức giao thoa với một phần hoặc voxel khác.

Mẫu mã sau cho thấy cách sự kiện Touched có thể được kết nối với một hàm onTouched() tùy chỉnh. Lưu ý rằng sự kiện gửi tham số otherPart đến hàm, cho biết 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 .. " đã va chạm với " .. otherPart.Name)
end
part.Touched:Connect(onTouched)

Lưu ý rằng sự kiện Touched có thể được kích hoạt nhiều lần trong thời gian ngắn dựa trên các va chạm vật lý tinh tế, chẳng hạn như khi một đối tượng di chuyển "ngã" vào vị trí nghỉ 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 Touched hơn mức cần thiết, bạn có thể triển khai một hệ thống chống đồng bộ đơn giản điều chỉnh thời gian "cooldown" thông qua một thuộc tính instance.

Va chạm Phần Với Thời Gian 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 .. " đã va chạm với " .. otherPart.Name)
part:SetAttribute("Touched", true) -- Đặt thuộc tính thành true
task.wait(COOLDOWN_TIME) -- Chờ thời gian cooldown
part:SetAttribute("Touched", false) -- Đặt lại thuộc tính
end
end
part.Touched:Connect(onTouched)

TouchEnded

Sự kiện TouchEnded được kích hoạt khi toàn bộ phạm vi va chạm của một BasePart thoát khỏi phạm vi của một BasePart khác hoặc một voxel Địa hình được lấp đầy. Nó chỉ được kích hoạt do mô phỏng vật lý và sẽ không được kích hoạt khi thuộc tính Position hoặc CFrame của phần được đặt một cách rõ ràng đến mức ngừng giao thoa với một phần hoặc voxel khác.

Mẫu mã sau cho thấy cách sự kiện TouchEnded có thể được kết nối với một hàm onTouchEnded() tùy chỉnh. Giống như Touched, sự kiện này gửi tham số otherPart đến hàm, cho biết phần khác tham gia.

Phát hiện Không Va Chạm

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " không còn tiếp xúc với " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)

Lọc va chạm

Lọc va chạm lọc xác định các phần vật lý nào va chạm với nhau. Bạn có thể cấu hình 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–phần với các instance NoCollisionConstraint.

Nhóm va chạm

Nhóm va chạm nhóm cho phép bạn gán BaseParts vào các nhóm riêng biệt và chỉ định liệu chúng có va chạm với nhau hay không. Các phần trong các nhóm không va chạm hoàn toàn đi qua nhau, ngay cả khi cả hai phần đều có thuộc tính CanCollide được đặt thành true.

Trong video trên, các đối tượng quay nằm trong các nhóm va chạm khác nhau đến nỗi chúng va chạm với các đối tượng có màu khác nhưng không va chạm với các đối tượng cùng màu với chúng

Bạn có thể dễ dàng thiết lập các nhóm va chạm thông qua trình biên tập Nhóm Va Chạm trong Studio, có thể truy cập thông qua menu Cửa sổ ⟩ 3D của Studio.

Trình biên tập hoạt động trong chế độ Danh sách View yêu thích việc neo sang bên trái hoặc bên phải của Studio, hoặc trong chế độ Bảng View rộng hơn, thích việc neo sang trên hoặc dưới.

Ví dụ Danh Sách View trong Trình Biên Tập Nhóm Va Chạm

Đăng ký nhóm

Trình biên tập bao gồm một nhóm va chạm Mặc định mà không thể đổi tên hoặc xóa. Tất cả các BaseParts tự động thuộc về 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:

  1. Nhấp vào nút Thêm Nhóm ở phần trên của bảng điều khiển trình biên tập, nhập tên nhóm mới, và nhấn Enter. Nhóm mới sẽ xuất hiện trong cả hai cột của chế độ xem danh sách, hoặc trong cả hai cột bên trái và hàng trên của chế độ xem bảng.

    Nhóm mới được thêm vào Trình Biên Tập Nhóm Va Chạm trong Danh Sách View
  2. Lặp lại quy trình nếu cần, 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 đổi tên.

    Nút và trường được chỉ định để đổi tên một nhóm trong Trình Biên Tập Nhóm Va Chạm

Cấu hình va chạm giữa các nhóm

Dưới 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 không cho các đối tượng trong một nhóm va chạm với các đối tượng trong một nhóm khác, hãy bỏ chọn ô trong hàng/cột tương ứng.

Trong ví dụ sau, các đối tượng trong nhóm Cubes sẽ không va chạm với các đối tượng trong nhóm Doors.

Nhóm được cấu hình trong Danh Sách View của Trình Biên Tập Nhóm Va Chạm

Gán các đối tượng vào các nhóm

Để gán các đối tượng vào các nhóm bạn đã đăng ký thông qua trình biên tập Studio:

  1. Chọn một hoặc nhiều BaseParts đủ điều kiện là một phần của nhóm va chạm.

  2. Gán chúng vào nhóm bằng cách nhấp vào nút cho hàng của nhóm đó. Các đối tượng chỉ có thể thuộc một nhóm va chạm tại một thời điểm, vì vậy việc đưa chúng vào một nhóm mới sẽ xóa chúng ra khỏi nhóm hiện tại.

    Nút cộng được chỉ định trong Trình Biên Tập Nhóm Va Chạm để thêm các phần đã chọn vào một nhóm

Khi đã được gán, nhóm mới sẽ được phản ánh dưới thuộc tính CollisionGroup của đối tượng.

Nhóm va chạm được chọn cho thấy thuộc tính CollisionGroup của phần

Nhóm va chạm StudioSelectable

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 nào là ứng viên để chọn khi nhấp vào trong không gian 3D. Các đối tượng có nhóm va chạm được gán không va chạm với StudioSelectable sẽ bị bỏ qua.

Ví dụ, nếu bạn có các điểm checkpoint trong một trò chơi đua xe mà các khu vực hiệu quả của chúng được xác định bởi các phần lớn trong suốt, bạn có thể gán chúng vào một nhóm va chạm Checkpoints và sau đó làm cho nhóm đó không thể va chạm với StudioSelectable để chúng không gây cản trở khi bạn đang chỉnh sửa hình học bản đồ dưới.

Nhóm điểm kiểm tra được cấu hình để không va chạm với nhóm StudioSelectable

Đối với mã plugin, khuyến nghị rằng bạn gán "StudioSelectable" làm bộ lọc nhóm va chạm trong RaycastParams của bạn khi tìm các phần dưới con trỏ. Điều này cho phép các plugin của bạn khớp với cơ chế chọn mà các nhà phát triển đã học để mong đợi từ các công cụ tích hợp sẵn của Studio.

Raycast chọn Plugin được khuyến nghị

local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Để theo quy ước
raycastParams.BruteForceAllSlow = true -- Để các phần có CanQuery là "false" có thể được chọn
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)

Lọc giữa các phần

Để ngăn không cho hai phần cụ thể va chạm với nhau mà không cần thiết lập nhóm va chạm, chẳng hạn như giữa bánh xe của một chiếc xe và thân xe, hãy xem xét ràng buộc Không Va Chạm. Các lợi ích bao gồm:

  • Không cần nhóm va chạm và/hoặc kịch bản cấu hình, vì vậy bạn có thể dễ dàng tạo và chia sẻ các mô hình với bộ lọc va chạm tùy chỉnh.
  • Các 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 giữa các 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 lối chơi thú vị nhưng không mong đợi, chẳng hạn như các nhân vật nhảy lên nhau để đến những 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ó bằng cách thực hiện kịch bản Script sau trong ServerScriptService.

Kịch bản - Vô hiệu hóa va chạm giữa các nhân vật

local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:CollisionGroupSetCollidable("Characters", "Characters", false)
local function onDescendantAdded(descendant)
-- Đặt nhóm va chạm cho bất kỳ phần nào là con cháu
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Characters"
end
end
local function onCharacterAdded(character)
-- Xử lý các đối tượng con hiện có và mới cho thiết lập vật lý
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- Phát hiện khi nhân vật của người chơi được thêm vào
player.CharacterAdded:Connect(onCharacterAdded)
end)

Va chạm giữa các mô hình

Các đối tượng Model là các container cho các 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 các sự kiện BasePart.Touched hoặc BasePart.TouchEnded. Để xác định xem một mô hình có kích hoạt các sự kiện va chạm hay không, bạn cần lặp qua các phần tử con của nó và kết nối các hàm onTouched()onTouchEnded() tùy chỉnh cho mỗi phần tử BasePart.

Mẫu mã sau kết nối tất cả các BaseParts của một mô hình nhiều phần với các 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 phần của mô hình giao thoa với chính nó
if otherPart:IsDescendantOf(model) then return end
-- Tăng số đếm các phần của mô hình đang chạm
numTouchingParts += 1
print(model.Name, "giao thoa với", otherPart.Name, "| Các phần của mô hình chạm:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Bỏ qua các phần của mô hình không còn giao thoa với chính nó
if otherPart:IsDescendantOf(model) then return end
-- Giảm số đếm các phần của mô hình đang chạm
numTouchingParts -= 1
print(model.Name, "không còn giao thoa với", otherPart.Name, "| Các phần của mô hình chạm:", 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ô hình mesh và mô hình rắn

MeshPartPartOperation (các phần được nối bởi mô hình rắn) là các lớp con của BasePart, vì vậy các mạng và các phần đã được mô hình rắn đều kế thừa các sự kiện va chạm và các tùy chọn lọc va chạm như các phần bình thường. Tuy nhiên, vì các mạng và các phần đã được mô hình rắn thường có hình dạng phức tạp hơn, chúng có thuộc tính đặc biệt CollisionFidelity xác định độ chính xác của các ranh giới vật lý so với hình ảnh hiển thị cho việc 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à ảnh hưởng đến hiệu suất từ thấp đến cao:

  • Hộp — Tạo một hộp va chạm bao, lý tưởng cho các đối tượng nhỏ hoặc không tương tác.
  • Vỏ — Tạo ra một hình vỏ lồi, phù hợp cho các đối tượng có các phần lõm hoặc khoang ít nổi bật.
  • Mặc định — Tạo ra một hình dạng va chạm ước lượng hỗ trợ độ lồi, thích ứng cho các đối tượng phức tạp có nhu cầu tương tác kiểu chi tiết vừa phải.
  • Phân Giải Chính Xác — Cung cấp độ chính xác cao nhất nhưng vẫn không phải là một đại diện 1:1 của hình ảnh hiển thị. Tùy chọn này có chi phí hiệu suất cao nhất và mất nhiều thời gian hơn để máy chủ tính toán.
Mạng gốc của tháp lâu đài

Để biết thêm thông tin về ảnh hưởng 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, hãy xem Tối ưu hóa hiệu suất.

©2026 Roblox Corporation. Roblox, logo Roblox và Powering Imagination là các nhãn hiệu đã đăng ký và chưa đăng ký của chúng tôi tại Hoa Kỳ và các quốc gia khác.