Sebuah tabrakan terjadi ketika dua objek 3D bersentuhan di dalam dunia 3D. Untuk penanganan tabrakan yang disesuaikan, BasePart memiliki serangkaian peristiwa tabrakan dan teknik penyaringan tabrakan, sehingga Anda dapat mengontrol objek fisik mana yang bertabrakan dengan yang lain.
Peristiwa tabrakan
Peristiwa tabrakan terjadi ketika dua BaseParts bersentuhan atau berhenti bersentuhan di dunia 3D. Anda dapat mendeteksi tabrakan ini melalui peristiwa Touched dan TouchEnded yang terjadi terlepas dari nilai properti CanCollide dari masing-masing bagian. Saat mempertimbangkan penanganan tabrakan pada bagian, perhatikan hal berikut:
- Properti CanTouch dari sebuah bagian menentukan apakah itu memicu peristiwa tabrakan. Jika diatur ke false, baik Touched maupun TouchEnded tidak akan dipicu.
- Properti CanCollide dari sebuah bagian mempengaruhi apakah itu akan secara fisik bertabrakan dengan bagian lain dan menyebabkan gaya bekerja pada mereka. Bahkan jika CanCollide dinonaktifkan untuk sebuah bagian, Anda dapat mendeteksi sentuhan dan tidak-sentuhan melalui peristiwa Touched dan TouchEnded.
- Peristiwa Touched dan TouchEnded hanya dipicu sebagai hasil dari gerakan fisik, bukan dari perubahan Position atau CFrame yang menyebabkan sebuah bagian berinteraksi atau berhenti berinteraksi dengan bagian lain.
Touched
Peristiwa Touched dipicu ketika sebuah BasePart bersentuhan dengan yang lain, atau dengan voxel Terrain. Ini hanya dipicu sebagai hasil dari simulasi fisik dan tidak akan dipicu ketika Position atau CFrame bagian diatur secara eksplisit sehingga berinteraksi dengan bagian atau voxel lain.
Pola kode berikut menunjukkan bagaimana peristiwa Touched dapat dihubungkan ke fungsi kustom onTouched(). Perhatikan bahwa peristiwa ini mengirim argumen otherPart ke fungsi, menunjukkan bagian lain yang terlibat dalam tabrakan.
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 dipicu beberapa kali dalam waktu singkat berdasarkan tabrakan fisik yang halus, seperti ketika objek bergerak "menetap" ke posisi istirahat atau ketika tabrakan melibatkan model multi-bagian. Untuk menghindari pemicu lebih banyak peristiwa Touched daripada yang diperlukan, Anda dapat menerapkan sistem debounce sederhana yang memberlakukan periode "cooldown" melalui sebuah atribut.
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) -- Atur atribut ke true
task.wait(COOLDOWN_TIME) -- Tunggu durasi cooldown
part:SetAttribute("Touched", false) -- Reset atribut
end
end
part.Touched:Connect(onTouched)TouchEnded
Peristiwa TouchEnded dipicu ketika seluruh batas tabrakan dari sebuah BasePart keluar dari batas BasePart lain atau voxel Terrain yang terisi. Ini hanya dipicu sebagai hasil dari simulasi fisik dan tidak akan dipicu ketika Position atau CFrame bagian diatur secara eksplisit sehingga berhenti berinteraksi dengan bagian atau voxel lain.
Pola kode berikut menunjukkan bagaimana peristiwa TouchEnded dapat dihubungkan ke fungsi kustom onTouchEnded(). Seperti Touched, peristiwa ini mengirim argumen otherPart ke fungsi, menunjukkan bagian lain yang terlibat.
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 tabrakan mendefinisikan bagian fisik mana yang bertabrakan dengan yang lain. Anda dapat mengonfigurasi penyaringan untuk banyak objek melalui grup tabrakan atau Anda dapat mengontrol tabrakan pada basis bagian-ke-bagian dengan instansi NoCollisionConstraint.
Grup tabrakan
Grup tabrakan memungkinkan Anda menetapkan BaseParts ke grup yang ditentukan dan menentukan apakah mereka bertabrakan dengan objek di grup lain. Bagian dalam grup yang tidak bertabrakan akan melewati satu sama lain sepenuhnya, bahkan jika kedua bagian memiliki properti CanCollide diatur ke true. Grup tabrakan dibuat dan dikonfigurasi berdasarkan Workspace atau WorldModel.
Anda dapat dengan mudah mengatur grup tabrakan melalui editor Grup Tabrakan di Studio, yang dapat diakses melalui menu Window ⟩ 3D di Studio.
Daftarkan grup
Workspace menyimpan status grup tabrakan yang dapat dikonfigurasi sendiri. Selain itu, setiap WorldModel dapat memilih untuk menggunakan grup tabrakan mereka sendiri untuk kueri.
Editor ini mencakup satu grup tabrakan Default yang tidak dapat diubah namanya atau dihapus. Semua BaseParts secara otomatis termasuk dalam grup default ini kecuali ditugaskan ke grup lain, yang berarti bahwa mereka akan bertabrakan dengan semua objek lain dalam grup Default.
Untuk membuat grup tabrakan baru:
Secara default, grup terdaftar di Workspace, tetapi jika Anda memiliki setidaknya satu WorldModel di tempat Anda, dropdown pilihan akan muncul di bagian atas editor grup tabrakan. Gunakan dropdown untuk mengonfigurasi grup tabrakan di berbagai instansi WorldModel.

Untuk setiap WorldModel, Anda dapat mengaktifkan Gunakan grup tabrakan Workspace untuk membuatnya menggunakan grup tabrakan Workspace untuk kuerinya.

Klik tombol Tambah Grup 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 unik dan deskriptif untuk setiap grup. Perhatikan bahwa Anda dapat mengubah nama grup selama pengembangan dengan mengklik di bidangnya, atau dengan memilihnya dan mengklik tombol ubah nama.

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 kotak di baris/kolom yang sesuai.
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 ⊕ untuk barisnya. Objek hanya dapat menjadi bagian dari satu grup tabrakan pada satu waktu, jadi menempatkan mereka dalam grup baru akan menghapus mereka dari grup saat ini.

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

Grup StudioSelectable
Alat di Studio menggunakan sistem penyaringan tabrakan untuk menentukan objek mana yang menjadi kandidat untuk dipilih saat mengklik di viewport 3D. Objek yang grup tabrakannya ditetapkan tidak bertabrakan dengan StudioSelectable akan diabaikan.
Sebagai contoh, jika Anda memiliki checkpoint dalam permainan balap yang area efektifnya didefinisikan oleh bagian transparan besar, Anda dapat menetapkannya ke grup tabrakan Checkpoints dan kemudian membuat grup itu tidak dapat bertabrakan dengan StudioSelectable sehingga tidak mengganggu saat Anda mengedit geometri peta yang mendasarinya.

Untuk kode plugin, disarankan agar Anda menetapkan "StudioSelectable" sebagai filter grup tabrakan dari RaycastParams Anda saat mencari bagian di bawah kursor. Ini memungkinkan plugin Anda untuk mencocokkan mekanika pemilihan yang telah dipelajari oleh pembuat dari alat Studio bawaan.
local UserInputService = game:GetService("UserInputService")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Untuk mengikuti konvensi
raycastParams.BruteForceAllSlow = true -- Sehingga bagian dengan CanQuery "false" dapat dipilih
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)Penyaringan bagian-ke-bagian
Untuk mencegah tabrakan antara dua bagian tertentu tanpa menyiapkan grup tabrakan, seperti antara roda kendaraan dan sasisnya, 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 masih dapat bertabrakan dengan objek lain.
Nonaktifkan tabrakan karakter
Karakter pemain Roblox bertabrakan satu sama lain secara default. Ini dapat menyebabkan permainan yang menarik tetapi tidak diinginkan, seperti karakter melompat di atas satu sama lain untuk mencapai area tertentu. Jika perilaku ini tidak diinginkan, Anda dapat mencegahnya melalui Script berikut di ServerScriptService.
local Players = game:GetService("Players")
workspace:RegisterCollisionGroup("Characters")
workspace: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 ketika karakter pemain ditambahkan
player.CharacterAdded:Connect(onCharacterAdded)
end)Tabrakan model
Objek Model adalah wadah untuk bagian daripada mewarisi dari BasePart, sehingga mereka tidak dapat terhubung langsung ke peristiwa BasePart.Touched atau BasePart.TouchEnded. Untuk menentukan apakah sebuah model memicu peristiwa tabrakan, Anda perlu melakukan loop melalui anak-anaknya dan menghubungkan fungsi kustom onTouched() dan onTouchEnded() ke setiap anak BasePart.
Contoh kode berikut menghubungkan semua BaseParts dari model multi-bagian ke peristiwa tabrakan dan melacak jumlah total tabrakan dengan bagian lain.
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Abaikan instansi model yang berinteraksi dengan dirinya sendiri
if otherPart:IsDescendantOf(model) then return end
-- Tingkatkan jumlah bagian model yang bersentuhan
numTouchingParts += 1
print(model.Name, "berinteraksi dengan", otherPart.Name, "| Bagian model yang bersentuhan:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Abaikan instansi model yang tidak berinteraksi dengan dirinya sendiri
if otherPart:IsDescendantOf(model) then return end
-- Kurangi jumlah bagian model yang bersentuhan
numTouchingParts -= 1
print(model.Name, "tidak berinteraksi lagi dengan", 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
endTabrakan model mesh dan solid
MeshPart dan PartOperation (bagian yang digabungkan melalui model solid) adalah subclass dari BasePart, sehingga bagian mesh dan model solid mewarisi opsi peristiwa tabrakan dan penyaringan tabrakan yang sama seperti bagian biasa. Namun, karena bagian mesh dan model solid biasanya memiliki geometri yang lebih kompleks, mereka memiliki properti CollisionFidelity yang menentukan seberapa tepat batas fisik sejajar dengan representasi visual untuk penanganan tabrakan.
Properti CollisionFidelity memiliki opsi berikut, dalam urutan fidelitas dan dampak kinerja dari yang terendah hingga tertinggi:
- Box — Membuat kotak tabrakan pembatas, ideal untuk objek kecil atau tidak interaktif.
- Hull — Menghasilkan hull cembung, cocok untuk objek dengan lekukan atau rongga yang kurang mencolok.
- Default — Menghasilkan bentuk tabrakan perkiraan yang mendukung kekonkavan, cocok untuk objek kompleks dengan kebutuhan interaksi semi-rinci.
- PreciseConvexDecomposition — Menawarkan fidelitas paling tepat tetapi tetap bukan representasi 1:1 dari visual. Opsi ini memiliki biaya kinerja paling mahal dan memerlukan waktu lebih lama bagi mesin untuk menghitung.

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