Een botsing vindt plaats wanneer twee 3D-objecten contact maken binnen de 3D-wereld. Voor aangepaste botsingsverwerking heeft BasePart een set van botsingsevents en botsingsfiltering technieken, zodat je kunt bepalen welke fysieke assemblages met elkaar botsen.
Botsingsevents
Botsing events vinden plaats wanneer twee BaseParts elkaar aanraken of stoppen met aanraken in de 3D-wereld. Je kunt deze botsingen detecteren via de Touched en TouchEnded events die plaatsvinden, ongeacht de waarde van de CanCollide eigenschap van elk onderdeel. Houd bij het overwegen van botsingsverwerking op onderdelen het volgende in gedachten:
- De CanTouch eigenschap van een onderdeel bepaalt of het botsingsevents activeert. Als deze is ingesteld op false, zullen noch Touched noch TouchEnded worden geactiveerd.
- De CanCollide eigenschap van een onderdeel beïnvloedt of het fysiek zal botsen met andere onderdelen en krachten op hen zal uitoefenen. Zelfs als CanCollide is uitgeschakeld voor een onderdeel, kun je aanraking en niet-aanraking detecteren via de Touched en TouchEnded events.
- De Touched en TouchEnded events worden alleen geactiveerd als gevolg van fysieke beweging, niet van een Position of CFrame wijzigingen die ervoor zorgen dat een onderdeel een ander onderdeel doorkruist of stopt met doorkruisen.
Aangeraakt
Het Touched event wordt geactiveerd wanneer een BasePart in contact komt met een ander, of met een Terrain voxel. Het wordt alleen geactiveerd als gevolg van fysieke simulatie en zal niet worden geactiveerd wanneer de Position of CFrame van het onderdeel expliciet is ingesteld zodat het een ander onderdeel of voxel doorkruist.
Het volgende codepatroon toont hoe het Touched event kan worden verbonden met een aangepaste onTouched() functie. Merk op dat het event het otherPart argument naar de functie verzendt, wat het andere onderdeel aangeeft dat betrokken is bij de botsing.
local part = workspace.Part
local function onTouched(otherPart)
print(part.Name .. " botste tegen " .. otherPart.Name)
end
part.Touched:Connect(onTouched)Merk op dat het Touched event meerdere keren snel achter elkaar kan worden geactiveerd op basis van subtiele fysieke botsingen, zoals wanneer een bewegend object "tot rust komt" in een rustpositie of wanneer een botsing een multi-part model betreft. Om te voorkomen dat er meer Touched events worden geactiveerd dan nodig, kun je een eenvoudig debounce-systeem implementeren dat een "cooldown"-periode afdwingt via een instantie attribuut.
local part = workspace.Part
local COOLDOWN_TIME = 1
local function onTouched(otherPart)
if not part:GetAttribute("Touched") then
print(part.Name .. " botste tegen " .. otherPart.Name)
part:SetAttribute("Touched", true) -- Stel attribuut in op true
task.wait(COOLDOWN_TIME) -- Wacht op cooldown duur
part:SetAttribute("Touched", false) -- Reset attribuut
end
end
part.Touched:Connect(onTouched)TouchEnded
Het TouchEnded event wordt geactiveerd wanneer de gehele botsingsgrenzen van een BasePart de grenzen van een ander BasePart of een gevulde Terrain voxel verlaat. Het wordt alleen geactiveerd als gevolg van fysieke simulatie en zal niet worden geactiveerd wanneer de Position of CFrame van het onderdeel expliciet is ingesteld zodat het stopt met doorkruisen van een ander onderdeel of voxel.
Het volgende codepatroon toont hoe het TouchEnded event kan worden verbonden met een aangepaste onTouchEnded() functie. Net als bij Touched, verzendt het event het otherPart argument naar de functie, wat het andere onderdeel aangeeft dat betrokken is.
local part = workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " raakt niet langer " .. otherPart.Name aan)
end
part.TouchEnded:Connect(onTouchEnded)Botsingssamenvattingen
Touched vertelt je dat er een botsing heeft plaatsgevonden, maar niet waar het is gebeurd, uit welke richting het kwam, of hoe hard het was. Voor gedetailleerde contactgegevens van de fysica-engine, roep je BindToCollisionSummaries() aan op een onderdeel. Het neemt een callback en retourneert een RBXScriptConnection die je kunt loskoppelen wanneer je de gegevens niet langer nodig hebt. Dit is een aparte API van Touched, dus roep het niet aan vanuit een Touched handler.
De callback wordt eenmaal per frame uitgevoerd, nadat de fysica-stap is voltooid. Het ontvangt een tabel met een samenvatting van elke botsing waarbij het onderdeel betrokken was tijdens dat frame. Elke samenvatting beschrijft één contactpatch tussen het geabonneerde onderdeel en een ander onderdeel. Samenvattingen zijn bevroren en kunnen niet worden gewijzigd. Elke heeft deze velden:
| Veld | Type | Beschrijving |
|---|---|---|
| Time | number | Simulatietijd van de substap. |
| Part0 | BasePart | Het geabonneerde onderdeel. |
| Part1 | BasePart | Het andere onderdeel in het paar. |
| Point | Vector3 | Gemiddeld contactpunt, in wereldruimte. |
| Normal | Vector3 | Eenheidsnormaal. Het wijst altijd weg van Part0. |
| RelativeVelocity | Vector3 | Snelheid van Part1 ten opzichte van Part0 op het contactpunt, gemeten voordat de oplosser de botsing oplost. |
| Area | number | Geschatte oppervlakte van de contactpatch. |
Om de frontale impact snelheid te krijgen, neem je het scalair product van RelativeVelocity en Normal. Om glijdende botsingen of schuiven te detecteren, gebruik je de tangentiële component van RelativeVelocity. Als je een waarde wilt die dichter bij een kracht ligt, combineer dan de snelheid met de AssemblyMass van de onderdelen.
local part = workspace.Part
local function onCollision(summaries)
for _, summary in summaries do
local impactSpeed = summary.RelativeVelocity:Dot(summary.Normal)
if impactSpeed > 10 then
print("Harde impact bij", summary.Point, "met snelheid", impactSpeed)
end
end
end
local connection = part:BindToCollisionSummaries(onCollision)
-- Later, wanneer je de samenvattingen niet langer nodig hebt
connection:Disconnect()Houd het volgende in gedachten wanneer je botsingssamenvattingen gebruikt:
- Samenvattingen worden alleen gegenereerd op de netwerk eigenaar die de fysica-simulatie uitvoert, wat een client of de server kan zijn. Ze worden niet gerepliceerd. Als andere clients op de hoogte moeten zijn van een botsing, verwerk dan de samenvatting en stuur alleen de gegevens die ze nodig hebben via je eigen remote event.
- Onderdelen met CanCollide ingesteld op false produceren geen botsingssamenvattingen.
- Complexe niet-convexe onderdelen kunnen meer dan één samenvatting voor hetzelfde paar onderdelen produceren.
- Contacten tussen twee slapende onderdelen worden niet geregistreerd.
- De verwerkingskosten groeien met het aantal geabonneerde onderdelen, niet met het totale aantal botsingen in de plaats.
Botsingsfiltering
Botsing filtering definieert welke fysieke onderdelen met elkaar botsen. Je kunt filtering configureren voor talrijke objecten via botsingsgroepen of je kunt botsingen op een deel-tot-deel basis regelen met NoCollisionConstraint instanties.
Botsingsgroepen
Botsing groepen stellen je in staat om BaseParts aan specifieke groepen toe te wijzen en te specificeren of ze al dan niet botsen met die in andere groepen. Onderdelen binnen niet-botsende groepen passeren elkaar volledig, zelfs als beide onderdelen hun CanCollide eigenschap op true hebben ingesteld. Botsingsgroepen worden gemaakt en geconfigureerd op basis van Workspace of WorldModel.
Je kunt botsingsgroepen eenvoudig instellen via de Botsingsgroepen editor van Studio, toegankelijk via het Venster ⟩ 3D menu.
Groepen registreren
Workspace slaat zijn eigen configureerbare staat van botsingsgroepen op. Bovendien kan elke WorldModel ervoor kiezen om zijn eigen botsingsgroepen te gebruiken voor queries.
De editor bevat één Standaard botsingsgroep die niet kan worden hernoemd of verwijderd. Alle BaseParts behoren automatisch tot deze standaardgroep, tenzij ze aan een andere groep zijn toegewezen, wat betekent dat ze met alle andere objecten in de Standaard groep zullen botsen.
Om een nieuwe botsingsgroep te maken:
Standaard worden groepen geregistreerd op Workspace, maar als je ten minste één WorldModel in je plaats hebt, verschijnt er een keuzedropdown bovenaan de botsingsgroepeneditor. Gebruik de dropdown om botsingsgroepen over verschillende WorldModel instanties te configureren.

Voor elke WorldModel kun je Gebruik Workspace-botsingsgroepen inschakelen om het te laten gebruik maken van Workspace botsingsgroepen voor zijn queries.

Klik op de Groep Toevoegen knop bovenaan het editorpaneel, voer een nieuwe groepsnaam in en druk op Enter. De nieuwe groep verschijnt in beide kolommen van de lijstweergave, of in zowel de linkerkolom als de bovenste rij van de tabelweergave.

Herhaal het proces indien nodig, kies een unieke en beschrijvende naam voor elke groep. Merk op dat je de naam van een groep tijdens de ontwikkeling kunt wijzigen door in het veld te klikken, of door deze te selecteren en op de hernoemen knop te klikken.

Groepsbotsingen configureren
Onder standaardconfiguratie botsen objecten in alle groepen met elkaar. Om te voorkomen dat objecten in één groep botsen met objecten in een andere groep, vink het vakje in de respectieve rij/kolom uit.
In het volgende voorbeeld zullen objecten in de Cubes groep niet botsen met objecten in de Doors groep.

Objecten aan groepen toewijzen
Om objecten toe te wijzen aan groepen die je hebt geregistreerd via de Studio-editor:
Selecteer een of meer BaseParts die kwalificeren als onderdeel van een botsingsgroep.
Wijs ze toe aan de groep door op de ⊕ knop voor de rij te klikken. Objecten kunnen slechts tot één botsingsgroep tegelijk behoren, dus ze in een nieuwe groep plaatsen verwijdert ze uit hun huidige groep.

Zodra toegewezen, wordt de nieuwe groep weergegeven onder de CollisionGroup eigenschap van het object.

StudioSelectable groep
Tools in Studio gebruiken het botsingsfilteringssysteem om te bepalen welke objecten kandidaten zijn voor selectie bij het klikken in de 3D-weergave. Objecten waarvan de toegewezen botsingsgroep niet botst met StudioSelectable worden genegeerd.
Als je bijvoorbeeld checkpoints hebt in een racegame waarvan de effectieve gebieden zijn gedefinieerd door grote transparante onderdelen, kun je ze toewijzen aan een Checkpoints botsingsgroep en die groep vervolgens niet-botsbaar maken met StudioSelectable zodat ze niet in de weg staan tijdens het bewerken van de onderliggende kaartgeometrie.

Voor plugin-code is het aan te raden om "StudioSelectable" als het botsingsgroepfilter van je RaycastParams toe te wijzen bij het vinden van onderdelen onder de cursor. Dit stelt je plugins in staat om overeen te komen met de selectiemechanica die makers hebben geleerd te verwachten van ingebouwde Studio-tools.
local UserInputService = game:GetService("UserInputService")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Om de conventie te volgen
raycastParams.BruteForceAllSlow = true -- Zodat onderdelen met CanQuery van "false" geselecteerd kunnen worden
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)Deel-tot-deel filtering
Om botsingen tussen twee specifieke onderdelen te voorkomen zonder botsingsgroepen op te zetten, zoals tussen een voertuigwiel en zijn chassis, overweeg de No Collision constraint. Voordelen zijn onder andere:
- Botsingsgroepen en/of configuratiescripts zijn niet vereist, zodat je eenvoudig modellen kunt maken en delen met aangepaste botsingsfiltering.
- Verbonden onderdelen zullen niet met elkaar botsen, maar ze kunnen nog steeds met andere objecten botsen.
Schakel karakterbotsingen uit
Roblox-spelerkarakters botsen standaard met elkaar. Dit kan leiden tot interessante maar onbedoelde gameplay, zoals karakters die op elkaar springen om specifieke gebieden te bereiken. Als dit gedrag ongewenst is, kun je het voorkomen via het volgende Script in ServerScriptService.
local Players = game:GetService("Players")
workspace:RegisterCollisionGroup("Characters")
workspace:CollisionGroupSetCollidable("Characters", "Characters", false)
local function onDescendantAdded(descendant)
-- Stel botsingsgroep in voor elk onderdeel afgeleid van
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Characters"
end
end
local function onCharacterAdded(character)
-- Verwerk bestaande en nieuwe afgeleiden voor fysica-instelling
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- Detecteer wanneer het karakter van de speler is toegevoegd
player.CharacterAdded:Connect(onCharacterAdded)
end)Modelbotsingen
Model objecten zijn containers voor onderdelen in plaats van afgeleid van BasePart, dus ze kunnen niet direct verbinding maken met BasePart.Touched of BasePart.TouchEnded events. Om te bepalen of een model een botsingsevent activeert, moet je door zijn kinderen lopen en de aangepaste onTouched() en onTouchEnded() functies aan elk kind BasePart verbinden.
Het volgende codevoorbeeld verbindt alle BaseParts van een multi-part model met botsingsevents en houdt het totale aantal botsingen met andere onderdelen bij.
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Negeer instanties van het model die met zichzelf overlappen
if otherPart:IsDescendantOf(model) then return end
-- Verhoog het aantal modelonderdelen dat aanraakt
numTouchingParts += 1
print(model.Name, "overlapte met", otherPart.Name, "| Modelonderdelen die aanraken:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Negeer instanties van het model die niet meer overlappen met zichzelf
if otherPart:IsDescendantOf(model) then return end
-- Verlaag het aantal modelonderdelen dat aanraakt
numTouchingParts -= 1
print(model.Name, "is niet meer overlapt met", otherPart.Name, "| Modelonderdelen die aanraken:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
endMesh en solide modelbotsingen
MeshPart en PartOperation (onderdelen samengevoegd door solide modellering) zijn subklassen van BasePart, zodat meshes en solide gemodelleerde onderdelen dezelfde botsingsevents en botsingsfiltering opties erven als reguliere onderdelen. Omdat meshes en solide gemodelleerde onderdelen meestal complexere geometrieën hebben, hebben ze een onderscheidende CollisionFidelity eigenschap die bepaalt hoe nauwkeurig de fysieke grenzen overeenkomen met de visuele representatie voor botsingsverwerking.
De CollisionFidelity eigenschap heeft de volgende opties, in volgorde van nauwkeurigheid en prestatie-impact van laag naar hoog:
- Doos — Creëert een begrenzende botsingsdoos, ideaal voor kleine of niet-interactieve objecten.
- Hul — Genereert een convexe hul, geschikt voor objecten met minder uitgesproken indeukingen of holtes.
- Standaard — Produceert een benaderende botsingsvorm die concaviteit ondersteunt, geschikt voor complexe objecten met semi-gedetailleerde interactiebehoeften.
- Nauwkeurige Convexe Decompositie — Biedt de meest nauwkeurige nauwkeurigheid, maar nog steeds geen 1:1 representatie van het visuele. Deze optie heeft de duurste prestatiekosten en duurt langer voor de engine om te berekenen.

Voor meer informatie over de prestatie-impact van botsingsnauwkeurigheid opties en hoe deze te mitigeren, zie prestatieoptimalisatie.