Sebuah tabrakan terjadi ketika dua objek 3D bersentuhan dalam dunia 3D. Untuk penanganan tabrakan yang disesuaikan, BasePart memiliki seperangkat peristiwa tabrakan dan teknik penyaringan tabrakan, sehingga Anda dapat mengontrol bagian fisik mana yang bertabrakan satu sama lain.
Peristiwa tabrakan
Peristiwa tabrakan events terjadi ketika dua BaseParts bersentuhan atau berhenti bersentuhan dalam dunia 3D. Anda dapat mendeteksi tabrakan ini melalui peristiwa Touched dan TouchEnded yang terjadi terlepas dari nilai properti CanCollide pada bagian tersebut. Ketika mempertimbangkan penanganan tabrakan pada bagian, perhatikan hal berikut:
- Properti CanTouch pada sebuah bagian menentukan apakah ia memicu peristiwa tabrakan. Jika diatur ke false, baik Touched maupun TouchEnded tidak akan terpicu.
- Properti CanCollide pada sebuah bagian mempengaruhi apakah itu akan secara fisik bertabrakan dengan bagian lain dan menyebabkan gaya bekerja pada mereka. Meskipun CanCollide dinonaktifkan untuk sebuah bagian, Anda dapat mendeteksi sentuhan dan tidak-sentuhan melalui peristiwa Touched dan TouchEnded.
- Peristiwa Touched dan TouchEnded hanya terpicu sebagai hasil gerakan fisik, bukan dari perubahan Position atau CFrame yang menyebabkan sebuah bagian bersinggungan atau berhenti bersinggungan dengan bagian lain.
Touched
Peristiwa Touched terpicu ketika BasePart bersentuhan dengan yang lain, atau dengan voxel Terrain. Itu hanya terpicu sebagai hasil dari simulasi fisik dan tidak akan terpicu ketika Position atau CFrame sebuah bagian diatur secara eksplisit sehingga bersinggungan dengan bagian lain atau voxel.
Pola kode berikut menunjukkan bagaimana peristiwa Touched dapat dihubungkan ke fungsi khusus onTouched(). Perhatikan bahwa peristiwa tersebut mengirim argumen otherPart ke fungsi, menunjukkan bagian lain yang terlibat dalam tabrakan.
Tabrakan Part
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouched(otherPart)
print(part.Name .. " bertabrakan dengan " .. otherPart.Name)
end
part.Touched:Connect(onTouched)
Perhatikan bahwa peristiwa Touched dapat terpicu beberapa kali dalam waktu singkat berdasarkan tabrakan fisik yang halus, seperti ketika objek bergerak "settle" ke posisi yang stabil atau saat tabrakan melibatkan sebuah model multi-bagian. Untuk menghindari memicu lebih banyak peristiwa Touched daripada yang diperlukan, Anda dapat menerapkan sistem debounce sederhana yang menerapkan periode "cooldown" melalui sebuah atribut instance.
Tabrakan Part Dengan 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 .. " bertabrakan dengan " .. otherPart.Name)
part:SetAttribute("Touched", true) -- Set atribut ke true
task.wait(COOLDOWN_TIME) -- Tunggu untuk durasi cooldown
part:SetAttribute("Touched", false) -- Reset atribut
end
end
part.Touched:Connect(onTouched)
TouchEnded
Peristiwa TouchEnded terpicu ketika seluruh batas tabrakan dari sebuah BasePart keluar dari batas BasePart lain atau voxel Terrain yang terisi. Itu hanya terpicu sebagai hasil dari simulasi fisik dan tidak akan terpicu ketika posisi Position atau CFrame diatur secara eksplisit sehingga tidak lagi bersinggungan dengan bagian lain atau voxel.
Pola kode berikut menunjukkan bagaimana peristiwa TouchEnded dapat dihubungkan ke fungsi khusus onTouchEnded(). Seperti Touched, peristiwa tersebut mengirim argumen otherPart ke fungsi, menunjukkan bagian lain yang terlibat.
Deteksi Non-Tabrakan
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " tidak lagi bersentuhan dengan " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)
Penyaringan tabrakan
Penyaringan filtering tabrakan mendefinisikan bagian fisik mana yang bertabrakan dengan yang lain. Anda dapat mengonfigurasi penyaringan untuk berbagai objek melalui grup tabrakan atau Anda dapat mengontrol tabrakan pada basis part-ke-part dengan instance NoCollisionConstraint.
Grup tabrakan
Grup tabrakan groups memungkinkan Anda menetapkan BaseParts ke grup khusus dan menentukan apakah mereka bertabrakan dengan yang berada di grup lain. Bagian dalam grup yang tidak bertabrakan sepenuhnya melewati satu sama lain, bahkan jika kedua bagian memiliki properti CanCollide yang diatur ke true.
Anda dapat dengan mudah mengatur grup tabrakan melalui editor Grup Tabrakan di Studio, yang dapat diakses melalui menu Window ⟩ 3D.
Editor berfungsi dalam Tampilan Daftar yang mendukung docking ke sisi kiri atau kanan Studio, atau dalam Tampilan Tabel yang lebih luas, yang mendukung docking ke atas atau bawah.

Daftarkan grup
Editor ini mencakup satu grup tabrakan Default yang tidak dapat diubah namanya atau dihapus. Semua BaseParts secara otomatis menjadi bagian dari grup default ini kecuali ditetapkan ke grup lain, yang berarti bahwa mereka akan bertabrakan dengan semua objek lain di grup Default.
Untuk membuat grup tabrakan baru:
Klik tombol Add Group di bagian atas panel editor, masukkan nama grup baru, dan tekan Enter. Grup baru akan muncul di kedua kolom tampilan daftar, atau di kolom kiri dan baris atas tampilan tabel.

Ulangi proses ini jika perlu, memilih nama yang unik dan deskriptif untuk masing-masing grup. Perhatikan bahwa Anda dapat mengubah nama grup selama pengembangan dengan mengklik bidangnya, atau dengan memilihnya dan mengklik tombol rename.

Konfigurasi tabrakan grup
Di bawah konfigurasi default, objek dalam semua grup bertabrakan satu sama lain. Untuk mencegah objek dalam satu grup bertabrakan dengan objek dalam grup lain, hapus centang pada kotak di baris/kolom yang bersangkutan.
Dalam contoh berikut, objek dalam grup Cubes tidak akan bertabrakan dengan objek dalam grup Doors.

Menetapkan objek ke grup
Untuk menetapkan objek ke grup yang telah Anda daftarkan melalui editor Studio:
Pilih satu atau lebih BaseParts yang memenuhi syarat sebagai bagian dari grup tabrakan.
Tetapkan mereka ke grup dengan mengklik tombol ⊕ di barisnya. Objek hanya dapat termasuk dalam satu grup tabrakan pada satu waktu, jadi menempatkannya dalam grup baru akan menghapusnya dari grup saat ini.

Setelah ditetapkan, grup baru akan tercermin di properti CollisionGroup objek tersebut.

Grup tabrakan StudioSelectable
Alat dalam Studio menggunakan sistem penyaringan tabrakan untuk menentukan objek mana yang menjadi kandidat untuk dipilih saat mengklik di viewport 3D. Objek yang ditetapkan grup tabrakan yang tidak bertabrakan dengan StudioSelectable akan diabaikan.
Sebagai contoh, jika Anda memiliki titik cek dalam pengalaman balap yang area efektifnya didefinisikan oleh bagian transparan besar, Anda dapat menetapkannya ke grup tabrakan Titik Cek dan kemudian membuat grup tersebut tidak bertabrakan dengan StudioSelectable sehingga tidak menghalangi saat Anda mengedit geometri peta di bawah.

Untuk kode plugin, sangat disarankan agar Anda menetapkan "StudioSelectable" sebagai penyaring grup tabrakan dari RaycastParams Anda saat mencari bagian di bawah kursor. Ini memungkinkan plugin Anda untuk mencocokkan mekanika pemilihan yang telah dipelajari para pembuat dari alat waspada bawaan Studio.
Rekomendasi Plugin Raycast Pemilihanlocal UserInputService = game:GetService("UserInputService")local Workspace = game:GetService("Workspace")local raycastParams = RaycastParams.new()raycastParams.CollisionGroup = "StudioSelectable" -- Untuk mengikuti konvensiraycastParams.BruteForceAllSlow = true -- Sehingga bagian dengan CanQuery "false" dapat dipilihlocal mouseLocation = UserInputService:GetMouseLocation()local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)
Penyaringan part-ke-part
Untuk mencegah tabrakan antara dua bagian tertentu tanpa mengatur grup tabrakan, seperti antara roda kendaraan dan bodinya, pertimbangkan kendala No Collision. Keuntungannya termasuk:
- Grup tabrakan dan/atau skrip konfigurasi tidak diperlukan, sehingga Anda dapat dengan mudah membuat dan membagikan model dengan penyaringan tabrakan yang disesuaikan.
- Bagian yang terhubung tidak akan bertabrakan satu sama lain, tetapi mereka tetap dapat bertabrakan dengan objek lain.
Nonaktifkan tabrakan karakter
Karakter pemain Roblox bertabrakan satu sama lain secara default. Ini dapat mengarah pada permainan yang menarik tetapi tidak terduga, seperti karakter melompat di atas satu sama lain untuk mencapai area tertentu. Jika perilaku ini tidak diinginkan, Anda dapat mencegahnya melalui skrip Script berikut dalam ServerScriptService.
Skrip - Nonaktifkan Tabrakan Karakter
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:CollisionGroupSetCollidable("Characters", "Characters", false)
local function onDescendantAdded(descendant)
-- Atur grup tabrakan untuk setiap bagian keturunan
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Characters"
end
end
local function onCharacterAdded(character)
-- Proses keturunan yang ada dan baru untuk pengaturan fisika
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- Deteksi kapan karakter pemain ditambahkan
player.CharacterAdded:Connect(onCharacterAdded)
end)
Tabrakan model
Objek Model adalah kontainer untuk bagian daripada mewarisi dari BasePart, jadi mereka tidak dapat langsung terhubung ke peristiwa BasePart.Touched atau BasePart.TouchEnded. Untuk menentukan apakah sebuah model memicu peristiwa tabrakan, Anda perlu mengulangi anak-anaknya dan menghubungkan fungsi khusus onTouched() dan onTouchEnded() ke setiap BasePart anak.
Sample kode berikut menghubungkan semua BaseParts dari model multi-bagian ke peristiwa tabrakan dan melacak jumlah total tabrakan dengan bagian lain.
Tabrakan Model
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Abaikan instance model yang saling bersinggungan
if otherPart:IsDescendantOf(model) then return end
-- Tambah jumlah bagian model yang bersentuhan
numTouchingParts += 1
print(model.Name, "bersinggungan dengan", otherPart.Name, "| Bagian model yang bersentuhan:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Abaikan instance model yang tidak saling bersinggungan
if otherPart:IsDescendantOf(model) then return end
-- Kurangi jumlah bagian model yang bersentuhan
numTouchingParts -= 1
print(model.Name, "tidak lagi bersinggungan dari", otherPart.Name, "| Bagian model yang bersentuhan:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
end
Tabrakan mesh dan model solid
MeshPart dan PartOperation (bagian yang digabungkan oleh solid modeling) adalah subclass dari BasePart, jadi mesh dan bagian model solid mewarisi peristiwa tabrakan dan opsi penyaringan tabrakan yang sama seperti bagian reguler. Namun, karena mesh dan bagian model solid biasanya memiliki geometri yang lebih kompleks, mereka memiliki properti khusus CollisionFidelity yang menentukan seberapa tepat batas fisik sejajar dengan representasi visual untuk penanganan tabrakan.
Properti CollisionFidelity memiliki opsi berikut, diurutkan berdasarkan fidelitas dan dampak kinerja dari yang terendah hingga tertinggi:
- Box — Membuat kotak tabrakan pembatas, ideal untuk objek kecil atau tidak interaktif.
- Hull — Menghasilkan cangkang konveks, cocok untuk objek dengan lekukan atau rongga yang kurang terlihat.
- Default — Menghasilkan bentuk tabrakan perkiraan yang mendukung kepresisian, cocok untuk objek kompleks dengan kebutuhan interaksi semi-rincian.
- PreciseConvexDecomposition — Menawarkan fidelitas yang paling tepat tetapi masih bukan representasi 1:1 dari visual. Opsi ini memiliki biaya kinerja yang paling mahal dan memerlukan lebih banyak waktu untuk dihitung oleh mesin.

Untuk informasi lebih lanjut tentang dampak kinerja dari opsi fidelitas tabrakan dan cara menguranginya, lihat Optimasi kinerja.