Kollisionen

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

Es kommt zu einer Kollision, wenn zwei 3D-Objekte innerhalb der 3D-Welt in Kontakt kommen.Für die anpassbare Kollisionsverarbeitung hat BasePart eine Reihe von Kollisionsereignissen und Kollisionsfiltern, so dass Sie kontrollieren können, welche physischen Montagemaschinen mit anderen kollidieren.

Kollisionsereignisse

Kollision Ereignisse treten auf, wenn zwei BaseParts sich in der 3D-Welt berühren oder aufhören, sich zu berühren.Du kannst diese Kollisionen durch die Touched- und TouchEnded-Ereignisse erkennen, die unabhängig von der Eigenschaftswert des Teils CanCollide auftreten.Wenn Sie die Kollisionsbearbeitung bei Teilen betrachten, beachten Sie gefolgte Profile:

  • Die Eigenschaft einer Teile CanTouch bestimmt, ob es Kollisionsereignisse auslöst. Wenn sie auf false gesetzt wird, werden weder Touched noch TouchEnded ausgelöst.
  • Die Eigenschaft einer Teile CanCollide beeinflusst, ob es physisch mit anderen Teilen kollidieren wird und Kräfte auf sie einwirken lässt.Selbst wenn CanCollide für einen Teil deaktiviert ist, können Sie Berührung und Nicht-Berührung durch Touched und TouchEnded Ereignisse erkennen.
  • Die Ereignisse Touched und TouchEnded feuern nur als Ergebnis der physischen Bewegung, nicht von Änderungen Position oder CFrame, die dazu führen, dass ein Teil sich mit oder aufhört, sich mit einem anderen Teil zu überlappen.
  • Die oberste Klasse Terrain erbt von BasePart, so dass Sie eine Kollisionsgruppe an Terrain zuweisen können, um zu bestimmen, ob andere BaseParts mit Terrain Voxelen kollidieren.

Berührt

Das Ereignis Touched wird ausgelöst, wenn ein BasePart mit einem anderen oder mit einem Terrain-Voxel in Kontakt kommt.Es feuert nur als Ergebnis von physischer Simulation und wird nicht feuern, wenn das Teil Position oder CFrame explizit so eingestellt ist, dass es sich mit einem anderen Teil oder Voxel überschneidet.

Das folgende Code-Muster zeigt, wie das Ereignis Touched mit einer benutzerdefinierten onTouched()-Funktion verbunden werden kann.Beachten Sie, dass das Ereignis das Argument otherPart an die Funktion sendet, das den anderen Teil der Kollision anzeigt, der beteiligt ist.

Teilkollision

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)

Beachten Sie, dass das Ereignis Touched mehrere Male in rascher Folge abfeuern kann, basierend auf subtilen physischen Kollisionen, wie z. B. wenn sich ein bewegendes Objekt in eine ruhende Position "setzt" oder wenn eine Kollision ein mehrteiliges Modell beinhaltet.Um zu vermeiden, mehr Touched Ereignisse auszulösen als notwendig, können Sie ein einfaches Debounce-System implementieren, das durch ein Instanz-Attribut eine "Abklingzeit" durchsetzt.

Teilkollision mit Abklingzeit

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) -- Attribut auf wahr setzen
task.wait(COOLDOWN_TIME) -- Warte auf Abklingzeitdauer
part:SetAttribute("Touched", false) -- Attribut zurücksetzen
end
end
part.Touched:Connect(onTouched)

Berührungsende

Das Ereignis TouchEnded wird ausgelöst, wenn die gesamten Kollisionsgrenzen eines BasePart die Grenzen eines anderen BasePart oder eines gefüllten Terrains-Voxels verlassen.Es feuert nur als Ergebnis von physischer Simulation und wird nicht abgefeuert, wenn das Teil Position oder CFrame explizit so eingestellt ist, dass es aufhört, sich mit einem anderen Teil oder Voxel zu überlappen.

Das folgende Code-Muster zeigt, wie das Ereignis TouchEnded mit einer benutzerdefinierten onTouchEnded()-Funktion verbunden werden kann.Wie Touched , sendet das Ereignis das otherPart -Argument an die Funktion, wodurch der andere beteiligte Teil angezeigt wird.

Nicht-Kollisionserkennung

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)

Kollisionsfilterung

Kollision Filterung definiert, mit welchen physischen Teilen andere kollidieren.Du kannst die Filterung für zahlreiche Objekte durch Kollisionsgruppen konfigurieren oder die Kollisionen auf einer Teil zu Teil Basis mit NoCollisionConstraint kontrollieren.

Kollisionsgruppen

Kollision Gruppen lassen dich zugewiesen BaseParts spezifizieren, ob sie mit denen in anderen Gruppen kollidieren oder nicht.Teile innerhalb nicht kollidierender Gruppen durchlaufen einander vollständig, auch wenn beide Teile ihre CanCollide Eigenschaft auf true gesetzt haben.

Im Video oben sind die sich drehenden Objekte in verschiedenen Kollisionsgruppen, die sie mit Objekten einer anderen Farbe kollidieren, aber nicht mit Objekten ihrer eigenen Farbe

Sie können Kollisionsgruppen einfach über den Kollisionsgruppen-Editor von Studio einrichten, der über die Schaltfläche Kollisionsgruppen in der Registerkarte Modell der Toolleiste zugänglich ist.

Collision Groups tool indicated in Model tab of Studio

Der Editor funktioniert entweder in Listenansicht , die das Anlegen an die linke oder rechte Seite von Studio favorisiert, oder in einer breiteren Tabelle-Ansicht , die das Anlegen an die Spitze oder den Boden favorisiert.

List View example in Collision Groups Editor

Gruppen registrieren

Der Editor enthält eine Standard- Kollisionsgruppe , die nicht umbenannt oder gelöscht werden kann.Alle BaseParts gehören automatisch zu dieser Standardgruppe, es sei denn, sie werden zu einer anderen Gruppe zugewiesen, was bedeutet, dass sie mit allen anderen Objekten in der Standardgruppe kollidieren werden.

Um eine neue Gruppezu erstellen:

  1. Klicken Sie auf die Schaltfläche Gruppe hinzufügen oben auf dem Editor-Panel, geben Sie einen neuen Gruppennamen ein und drücken Sie Enter.Die neue Gruppe erscheint in beiden Spalten der Ansichtoder in beiden linken Spalte und oberen Zeile der Ansicht.

    New group added to Collision Groups Editor in List View
  2. Wiederhole den Prozess, wenn nötig, und wähle einen einzigartigen und beschreibenden Namen für jede Gruppe.Beachten Sie, dass Sie den Namen einer Gruppe während der Entwicklung ändern können, indem Sie auf ihr Feld klicken oder es auswählen und die Schaltfläche umbenennen drücken.

    Button and field indicated for renaming a group in the Collision Groups Editor

Konfigurieren von Gruppenkollisionen

Unter der Standardkonfiguration stoßen Objekte in allen Gruppen aufeinander.Um zu verhindern, dass Objekte in einer Gruppe mit Objekten in einer anderen Gruppe kollidieren, deaktivieren Sie die Box in der jeweiligen Zeile/Säule.

Im folgenden Beispiel stoßen Objekte in der Kuben Gruppe nicht mit Objekten in der Türen Gruppe zusammen.

Group configured in List View of Collision Groups Editor

Zuordne Objekte zu Gruppen

Um Objekte auf Gruppen zuzuweisen, die du registriert hast durch den Studio-Editor:

  1. Wählen Sie eine oder mehrere BaseParts, die als Teil einer Gruppequalifiziert sind.

  2. Weisen Sie sie der Gruppe zu, indem Sie auf die Schaltfläche für ihre Zeile klicken.Objekte können nur einer Kollisionsgruppe gleichzeitig angehören, sodass das Platzieren in einer neuen Gruppe sie aus ihrer aktuellen Gruppe entfernt.

    Plus button indicated in Collision Groups Editor for adding selected parts to a group

Sobald vergeben, wird die neue Gruppe unter der Eigenschaftendes Objekts widergespiegelt.

Chosen collision group indicated as the part's CollisionGroup property

StudioSelectable Gruppe

Werkzeuge in Studio verwenden das Kollisionsfilterungssystem, um zu bestimmen, welche Objekte Kandidaten für die Auswahl sind, wenn im 3D-Ansichtsfenster geklickt wird.Objekte, deren zugewiesene Kollisionsgruppe nicht mit StudioSelectable kollidiert, werden ignoriert.

Wenn du beispielsweise Checkpoints in einem Renn-Erlebnis hast, deren effektive Bereiche durch große transparente Teile definiert sind, kannst du sie einer Checkpoints Kollisionsgruppe zuweisen und dann diese Gruppe nicht-kollidierbar machen mit StudioSelectable , damit sie nicht im Weg sind, wenn du die darunterliegende Kartengeometrie bearbeitest.

Checkpoints group configured to be non-collidable with StudioSelectable group

Für Codeswird empfohlen, "StudioSelectable" als Kollisionsgruppenfilter Ihrer RaycastParams zuzuweisen, wenn Sie Teile unter dem Cursor finden.Dies ermöglicht es deinen Plugins, die Auswahlmechanismen zu entsprechen, die Entwickler von integrierten Studio-Tools erwartet haben.

Empfohlene Plugin-Auswahl Raycast

local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Um der Konvention zu folgen
raycastParams.BruteForceAllSlow = true -- Damit Teile mit CanQuery von "false" ausgewählt werden können
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)

Teil-zu-Teil-Filterung

Um Kollisionen zwischen zwei bestimmten Teilen zu verhindern, ohne Kollisionsgruppen einzurichten, wie zwischen dem Rad eines Fahrzeugs und seinem Chassis, berücksichtigen Sie die Keine Kollision Einschränkung.Vorteile umfassen:

  • Kollisionsgruppen und/oder Konfigurationsskripte sind nicht erforderlich, so dass du Modelle leicht erstellen und mit angepasstem Kollisionsfiltering teilen kannst.
  • Verbundene Teile stoßen nicht miteinander zusammen, aber sie können immer noch mit anderen Objekten zusammenstoßen.

Charakter-Kollisionen deaktivieren

Roblox-Spielercharaktere stoßen standardmäßig aufeinander.Dies kann zu interessantem, aber unbeabsichtigtem Gameplayführen, wie zum Beispiel Charaktere springen aufeinander, um bestimmte Bereiche zu erreichen.Wenn dieses Verhalten unerwünscht ist, kannst du es durch das folgende Script in ServerScriptService verhindern.

Skript - Deaktivieren von Zeichenkollisionen

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)
-- Wenden Sie die Kollisionsgruppe auf alle vorhandenen Teile im Modell an
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)
-- Wenn der Spieler bereits einen Charakter hat, wenden Sie die Kollisionsgruppe sofort an
if player.Character then
setCollisionGroup(player.Character)
end
end)

Modellkollisionen

Model Objekte sind Container für Teile, anstatt von BasePart zu erben, können sie daher nicht direkt mit BasePart.Touched oder BasePart.TouchEnded Ereignissen verbunden werden.Um zu bestimmen, ob ein Modell Kollisionsereignisse auslöst, musst du durch seine Kinder gehen und die benutzerdefinierten onTouched()- und onTouchEnded()-Funktionen mit jedem Kind BasePart verbinden.

Das folgende Codebeispiel verbindet alle BaseParts eines mehrteiligen Modells mit Kollisionsereignissen und verfolgt die Gesamtzahl der Kollisionen mit anderen Teilen.

Modellkollision

local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignoriere Instanzen des Modells, die sich mit sich selbst überlappen
if otherPart:IsDescendantOf(model) then return end
-- Erhöhen Sie die Anzahl der berührenden Modellteile
numTouchingParts += 1
print(model.Name, "intersected with", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Ignoriere Instanzen des Modells, die sich nicht mit sich selbst überlappen
if otherPart:IsDescendantOf(model) then return end
-- Verringere die Anzahl der berührenden Modellteile
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

Mesh- und Solidmodell-Kollisionen

MeshPart und PartOperation (Teile, die durch Festkörpermodellierung verbunden sind) sind Unterklassen von BasePart , so erben Meshes und solide modellierte Teile die gleichen Kollisionsereignisse und Kollisionsfilteroptionen wie normale Teile.Allerdings haben Meshes und solide modellierte Teile in der Regel komplexere Geometrien, weshalb sie eine einzigartige CollisionFidelity Eigenschaft haben, die bestimmt, wie genau die physischen Grenzen mit der visuellen Darstellung für die Kollisionsverarbeitung übereinstimmen.

Die Eigenschaft CollisionFidelity hat die folgenden Optionen, in der Reihenfolge der Treue und der Leistungswirkung von niedrig bis hoch:

  • Box — Erstellt eine Auswahlbox, ideal für kleine oder nicht interaktive Objekte.
  • Rumpf — Erzeugt einen konvexen Rumpf, der für Objekte mit weniger ausgeprägten Vertiefungen oder Lücken geeignet ist.
  • Standard — Erzeugt eine ungefähre Kollisionsform, die eine Kerbverformung unterstützt, geeignet für komplexe Objekte mit semi-detaillierten Interaktionsbedürfnissen.
  • Präzise konvexe Decomposition — Bietet die genaueste Treue, ist aber immer noch keine 1:1-Darstellung des visuellen.Diese Option hat die teuerste Leistungskosten und dauert länger, bis die Engine berechnet wird.
Original mesh of castle tower

Für weitere Informationen über die Auswirkungen der Performance von Kollisionssicherheitsoptionen und wie sie gemildert werden, siehe Leistungsoptimierung.