Une collision se produit lorsque deux objets 3D entrent en contact dans le monde 3D. Pour une gestion personnalisée des collisions, BasePart dispose d'un ensemble d'événements de collision et de techniques de filtrage de collision, vous permettant de contrôler quels assemblages physiques entrent en collision avec d'autres.
Événements de collision
Les événements de collision se produisent lorsque deux BaseParts se touchent ou cessent de se toucher dans le monde 3D. Vous pouvez détecter ces collisions via les événements Touched et TouchEnded, qui se produisent indépendamment de la valeur de la propriété CanCollide de chaque partie. Lors de la prise en compte de la gestion des collisions sur les parties, notez ce qui suit :
- La propriété CanTouch d'une partie détermine si elle déclenche des événements de collision. Si elle est définie sur false, ni Touched ni TouchEnded ne seront déclenchés.
- La propriété CanCollide d'une partie affecte si elle va physiquement entrer en collision avec d'autres parties et provoquer des forces agissant sur elles. Même si CanCollide est désactivé pour une partie, vous pouvez détecter le contact et le non-contact via les événements Touched et TouchEnded.
- Les événements Touched et TouchEnded ne se déclenchent que suite à un mouvement physique, et non à des changements de Position ou CFrame qui provoquent une intersection ou un arrêt d'intersection avec une autre partie.
Touché
L'événement Touched se déclenche lorsqu'une BasePart entre en contact avec une autre, ou avec un voxel de Terrain. Il ne se déclenche que suite à une simulation physique et ne se déclenchera pas lorsque la Position ou la CFrame de la partie est explicitement définie de manière à ce qu'elle intersecte une autre partie ou un voxel.
Le modèle de code suivant montre comment l'événement Touched peut être connecté à une fonction personnalisée onTouched(). Notez que l'événement envoie l'argument otherPart à la fonction, indiquant l'autre partie impliquée dans la collision.
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouched(otherPart)
print(part.Name .. " a heurté " .. otherPart.Name)
end
part.Touched:Connect(onTouched)Notez que l'événement Touched peut se déclencher plusieurs fois en succession rapide en raison de collisions physiques subtiles, comme lorsque un objet en mouvement "se stabilise" dans une position de repos ou lorsqu'une collision implique un modèle multi-part. Pour éviter de déclencher plus d'événements Touched que nécessaire, vous pouvez mettre en œuvre un simple système de debounce qui impose une période de "refroidissement" via un attribut.
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 .. " a heurté " .. otherPart.Name)
part:SetAttribute("Touched", true) -- Définir l'attribut sur true
task.wait(COOLDOWN_TIME) -- Attendre la durée de refroidissement
part:SetAttribute("Touched", false) -- Réinitialiser l'attribut
end
end
part.Touched:Connect(onTouched)TouchEnded
L'événement TouchEnded se déclenche lorsque l'ensemble des limites de collision d'une BasePart sort des limites d'une autre BasePart ou d'un voxel de Terrain rempli. Il ne se déclenche que suite à une simulation physique et ne se déclenchera pas lorsque la Position ou la CFrame de la partie est explicitement définie de manière à ce qu'elle cesse d'intersecter une autre partie ou un voxel.
Le modèle de code suivant montre comment l'événement TouchEnded peut être connecté à une fonction personnalisée onTouchEnded(). Comme pour Touched, l'événement envoie l'argument otherPart à la fonction, indiquant l'autre partie impliquée.
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " ne touche plus " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)Filtrage de collision
Le filtrage de collision définit quelles parties physiques entrent en collision avec d'autres. Vous pouvez configurer le filtrage pour de nombreux objets via des groupes de collision ou vous pouvez contrôler les collisions sur une base partie-à-partie avec des instances NoCollisionConstraint.
Groupes de collision
Les groupes de collision vous permettent d'assigner des BaseParts à des groupes dédiés et de spécifier s'ils entrent ou non en collision avec ceux d'autres groupes. Les parties au sein de groupes non-collidants passent complètement à travers les autres, même si les deux parties ont leur propriété CanCollide définie sur true.
Vous pouvez facilement configurer des groupes de collision via l'éditeur Groupes de Collision de Studio, accessible via le menu Fenêtre ⟩ 3D de Studio.
L'éditeur fonctionne en mode Liste View, qui favorise le docking sur le côté gauche ou droit de Studio, ou en mode Table View, qui favorise le docking en haut ou en bas.

Enregistrer des groupes
L'éditeur comprend un groupe de collision Par défaut qui ne peut pas être renommé ou supprimé. Tous les BaseParts appartiennent automatiquement à ce groupe par défaut, sauf s'ils sont assignés à un autre groupe, ce qui signifie qu'ils entreront en collision avec tous les autres objets dans le groupe Par défaut.
Pour créer un nouveau groupe de collision :
Cliquez sur le bouton Ajouter un Groupe en haut du panneau de l'éditeur, entrez un nouveau nom de groupe et appuyez sur Entrée. Le nouveau groupe apparaît dans les deux colonnes de la vue liste, ou dans la colonne de gauche et la ligne supérieure de la vue table.

Répétez le processus si nécessaire, en choisissant un nom unique et descriptif pour chaque groupe. Notez que vous pouvez changer le nom d'un groupe pendant le développement en cliquant dans son champ, ou en le sélectionnant et en cliquant sur le bouton renommer.

Configurer les collisions de groupe
Sous la configuration par défaut, les objets de tous les groupes entrent en collision les uns avec les autres. Pour empêcher les objets d'un groupe d'entrer en collision avec des objets d'un autre groupe, décochez la case dans la ligne/colonne respective.
Dans l'exemple suivant, les objets du groupe Cubes ne entreront pas en collision avec les objets du groupe Portes.

Assigner des objets à des groupes
Pour assigner des objets à des groupes que vous avez enregistrés via l'éditeur Studio :
Sélectionnez une ou plusieurs BaseParts qui qualifient comme partie d'un groupe de collision.
Assignez-les au groupe en cliquant sur le bouton ⊕ pour sa ligne. Les objets ne peuvent appartenir qu'à un seul groupe de collision à la fois, donc les placer dans un nouveau groupe les retire de leur groupe actuel.

Une fois assigné, le nouveau groupe est reflété sous la propriété CollisionGroup de l'objet.

Groupe de collision StudioSelectable
Les outils dans Studio utilisent le système de filtrage de collision pour déterminer quels objets sont candidats à la sélection lors d'un clic dans la vue 3D. Les objets dont le groupe de collision assigné ne collidant pas avec StudioSelectable seront ignorés.
Par exemple, si vous avez des points de contrôle dans un jeu de course dont les zones effectives sont définies par de grandes parties transparentes, vous pouvez les assigner à un groupe de collision Points de Contrôle et ensuite rendre ce groupe non-collidable avec StudioSelectable afin qu'ils ne gênent pas lorsque vous éditez la géométrie sous-jacente de la carte.

Pour le code de plugin, il est recommandé d'assigner "StudioSelectable" comme filtre de groupe de collision de votre RaycastParams lors de la recherche de parties sous le curseur. Cela permet à vos plugins de correspondre aux mécaniques de sélection que les créateurs ont appris à attendre des outils intégrés de Studio.
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Pour suivre la convention
raycastParams.BruteForceAllSlow = true -- Pour que les parties avec CanQuery de "false" puissent être sélectionnées
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)Filtrage partie-à-partie
Pour empêcher les collisions entre deux parties spécifiques sans configurer des groupes de collision, comme entre la roue d'un véhicule et son châssis, envisagez la contrainte No Collision. Les avantages incluent :
- Les groupes de collision et/ou les scripts de configuration ne sont pas nécessaires, vous pouvez donc facilement créer et partager des modèles avec un filtrage de collision personnalisé.
- Les parties connectées ne vont pas entrer en collision les unes avec les autres, mais elles peuvent toujours entrer en collision avec d'autres objets.
Désactiver les collisions de personnage
Les personnages des joueurs Roblox entrent en collision les uns avec les autres par défaut. Cela peut conduire à un gameplay intéressant mais non désiré, comme des personnages sautant les uns sur les autres pour atteindre des zones spécifiques. Si ce comportement est indésirable, vous pouvez l'empêcher via le Script suivant dans ServerScriptService.
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
PhysicsService:RegisterCollisionGroup("Personnages")
PhysicsService:CollisionGroupSetCollidable("Personnages", "Personnages", false)
local function onDescendantAdded(descendant)
-- Définir le groupe de collision pour toute partie descendante
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Personnages"
end
end
local function onCharacterAdded(character)
-- Traiter les descendants existants et nouveaux pour la configuration physique
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- Détecter quand le personnage du joueur est ajouté
player.CharacterAdded:Connect(onCharacterAdded)
end)Collisions de modèle
Les objets Model sont des conteneurs pour des parties plutôt que d'hériter de BasePart, donc ils ne peuvent pas se connecter directement aux événements BasePart.Touched ou BasePart.TouchEnded. Pour déterminer si un modèle déclenche des événements de collision, vous devez parcourir ses enfants et connecter les fonctions personnalisées onTouched() et onTouchEnded() à chaque enfant BasePart.
Le code d'exemple suivant connecte toutes les BaseParts d'un modèle multi-part aux événements de collision et suit le nombre total de collisions avec d'autres parties.
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignorer les instances du modèle s'intersectant avec lui-même
if otherPart:IsDescendantOf(model) then return end
-- Augmenter le compte des parties du modèle touchant
numTouchingParts += 1
print(model.Name, "a intersecté", otherPart.Name, "| Parties du modèle touchant :", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Ignorer les instances du modèle ne s'intersectant plus avec lui-même
if otherPart:IsDescendantOf(model) then return end
-- Diminuer le compte des parties du modèle touchant
numTouchingParts -= 1
print(model.Name, "ne s'est plus intersecté avec", otherPart.Name, "| Parties du modèle touchant :", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
endCollisions de Mesh et de modèle solide
Les MeshPart et PartOperation (parties jointes par modélisation solide) sont des sous-classes de BasePart, donc les maillages et les parties modélisées solides héritent des mêmes événements de collision et options de filtrage de collision que les parties régulières. Cependant, comme les maillages et les parties modélisées solides ont généralement des géométries plus complexes, elles ont une propriété distinctive CollisionFidelity qui détermine à quel point les limites physiques s'alignent précisément avec la représentation visuelle pour la gestion des collisions.
La propriété CollisionFidelity a les options suivantes, par ordre de fidélité et d'impact sur les performances, du plus bas au plus élevé :
- Boîte — Crée une boîte de collision englobante, idéale pour les objets petits ou non interactifs.
- Coque — Génère une coque convexe, adaptée aux objets avec moins d'indentations ou de cavités prononcées.
- Par défaut — Produit une forme de collision approximative qui supporte la concavité, adaptée aux objets complexes avec des besoins d'interaction semi-détaillés.
- Décomposition Convexe Précise — Offre la fidélité la plus précise mais n'est toujours pas une représentation 1:1 de la visuelle. Cette option a le coût de performance le plus élevé et prend plus de temps pour que le moteur calcule.

Pour plus d'informations sur l'impact des performances des options de fidélité de collision et comment les atténuer, voir Optimisation des performances.