Les collisions

*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.

Une collision se produit lorsque deux objets 3D entrent en contact dans le monde 3D.Pour une manipulation de collision personnalisée, BasePart a un ensemble de événements de collision et de techniques de filtrage de collision, afin que vous puissiez contrôler les assemblages physiques qui se heurtent à d'autres.

Événements de collision

Les événements de collision se produisent lorsque deux touchent ou arrêtent de 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 propriété de chaque partie CanCollide.Lorsque vous envisagez la gestion de la collision sur les parties, notez ce qui suivre:

  • La propriété d'une partie détermine si elle déclenche des événements de collision. Si elle est définie sur , aucun des événements ou ne se déclenchera.
  • La propriété d'une partie affecte si elle va physiquement s'écraser avec d'autres parties et provoquer des forces pour les agir.Même si CanCollide est désactivé pour une partie, vous pouvez détecter la touche et le non-touche à travers Touched et TouchEnded événements.
  • Les événements Touched et TouchEnded ne se déclenchent que lors d'un mouvement physique physique , pas à partir d'un changement Position ou CFrame qui fait intersecter ou cesser l'intersection d'une partie avec une autre partie.
  • La classe de niveau supérieur hérite de , vous pouvez donc attribuer un groupe de collision à pour déterminer si d'autres collident avec Terrain des voxels.

Touché

L'événement Touched se déclenche lorsqu'un BasePart entre en contact avec un autre, ou avec un Terrain voxel.Il ne se déclenche qu'en raison de simulation physique et ne se déclenchera pas lorsque la partie sera explicitement définie de sorte 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.

Collision de parties

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)

Notez que l'événement peut se déclencher plusieurs fois en succession rapide en fonction de collisions physiques subtiles, telles que lorsqu'un objet en mouvement "se fixe" dans une position de repos ou lorsqu'une collision implique un modèle à plusieurs parties .Pour éviter d'activer plus d'événements Touched que nécessaire, vous pouvez mettre en œuvre un système simple de décalage qui impose une période de "recharge" via un attribut instance.

Collision de partie avec récupération

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) -- Définir l'attribut à vrai
task.wait(COOLDOWN_TIME) -- Attendez la durée de récupération
part:SetAttribute("Touched", false) -- Attribut de réinitialisation
end
end
part.Touched:Connect(onTouched)

Fin de la touche

L'événement se déclenche lorsque l'ensemble des limites de collision d'un quitte les limites d'un autre ou d'un voxel de terrain rempli.Il ne se déclenche qu'en raison de simulation physique et ne se déclenchera pas lorsque la partie sera explicitement définie de telle sorte qu'elle cessera d'intersectionner 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 Touched , l'événement envoie l'argument otherPart à la fonction, indiquant l'autre partie impliquée.

Détection non-collision

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)

Filtre de collision

Le filtre de collision définit les parties physiques qui se heurtent à d'autres.Vous pouvez configurer le filtrage pour de nombreux objets via groupes de collision ou vous pouvez contrôler les collisions sur une base partie à partie avec instances.

Groupes de collision

La collision groupes vous permet d'assigner BaseParts des groupes dédiés et de spécifier si oui ou non ils se heurtent à ceux d'autres groupes.Les parties dans des groupes non collisibles passent l'une à travers l'autre complètement, même si les deux parties ont leur propriété CanCollide définie à true.

Dans la vidéo ci-dessus, les objets tournants appartiennent à différents groupes de collision tels qu'ils se heurtent à des objets d'une autre couleur mais pas à des objets de leur propre couleur

Vous pouvez facilement configurer des groupes de collision via l'éditeur de groupes de collision de Studio, accessible en cliquant sur le bouton groupes de collision dans l'onglet modèle de la barre d'outils.

Collision Groups tool indicated in Model tab of Studio

L'éditeur fonctionne dans l'une des options suivantes vue en liste qui favorise le docking à gauche ou à droite de Studio, ou dans une vue de table plus large vue en table qui favorise le docking en haut ou en bas.

List View example in Collision Groups Editor

Enregistrer des groupes

L'éditeur inclut un groupe de collision par défaut par défaut qui ne peut pas être renommé ou supprimé.Tous les BaseParts appartiennent automatiquement à ce groupe par défaut à moins qu'ils ne soient attribués à un autre groupe, ce qui signifie qu'ils s'affronteront avec tous les autres objets du groupe par défaut .

Pour créer un nouveau groupe de collision :

  1. Cliquez sur le bouton Ajouter un groupe en haut du panneau de l'éditeur, entrez un nouveau nom de groupe et appuyez sur Enter .Le nouveau groupe apparaît dans les deux colonnes de la voiren liste ou dans les deux colonnes de la colonne de table et de la rangée supérieure.

    New group added to Collision Groups Editor in List View
  2. Répétez le processus si nécessaire, en choisissant un nom unique et descriptif pour chaque groupe.Remarquez que vous pouvez modifier 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 .

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

Configurer les collisions de groupe

Dans la configuration par défaut, les objets de tous les groupes se heurtent les uns aux autres.Pour empêcher les objets d'un groupe de se heurter à des objets d'un autre groupe, désélectionnez la case dans la colonne/ligne respective.

Dans l'exemple suivant, les objets du groupe Cubes ne s'affronteront pas avec les objets du groupe Portes .

Group configured in List View of Collision Groups Editor

Attribuer des objets à des groupes

Pour attribuer des objets à des groupes que vous avez enregistrés via l'éditeur Studio :

  1. Sélectionnez un ou plusieurs BaseParts qui se qualifient comme faisant partie d'un groupe de collision.

  2. Attribuez-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 éloigne de leur groupe actuel.

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

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

Chosen collision group indicated as the part's CollisionGroup property

groupede collision sélectionnable dans le studio

Les outils dans Studio utilisent le système de filtrage de collision pour déterminer quels objets sont candidats à la sélection lorsqu'on clique dans la fenêtre de jeu3D.Les objets dont le groupe de collision attribué ne fait pas pas de collision avec StudioSelectable seront ignorés.

Par exemple, si vous avez des points de contrôle dans une expérience de course dont les zones efficaces sont définies par de grandes parties transparentes, vous pouvez les attribuer à un groupe de collisions de 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 de la carte sous-jacente.

Checkpoints group configured to be non-collidable with StudioSelectable group

Pour le code du plugin, il est recommandé d'assigner "StudioSelectable" comme filtre de groupe de collision de votre RaycastParams lorsque vous trouvez des parties sous le curseur.Cela permet à vos plugins de correspondre aux mécanismes de sélection que les créateurs ont appris à attendre des outils intégrés de Studio.

Raycast de sélection de plugin recommandé

local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Pour suivre la convention
raycastParams.BruteForceAllSlow = true -- Ainsi, les parties avec CanQuery de « faux » peuvent ê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 de partie à partie

Pour empêcher les collisions entre deux parties spécifiques sans mettre en place de groupes de collisions, comme entre la roue d'un véhicule et son châssis, envisagez la contrainte Pas de 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 filtre de collision personnalisé.
  • Les parties connectées ne se heurteront pas les unes aux autres, mais elles peuvent toujours se heurter à d'autres objets.

Désactiver les collisions de caractères

Les personnages de joueur Roblox s'affrontent par défaut les uns les autres.Cela peut conduire à un partieintéressant mais non intentionnel, comme des personnages sautant les uns sur les autres pour atteindre des zones spécifiques.Si ce comportement n'est pas souhaitable, vous pouvez l'empêcher via le suivant Script dans ServerScriptService .

Script - Désactiver les collisions de caractères

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)
-- Appliquer le groupe de collision à toutes les parties existantes dans le modèlisation
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)
-- Si le joueur a déjà un personnage, appliquez le groupe de collision immédiatement
if player.Character then
setCollisionGroup(player.Character)
end
end)

Collisions de modèle

Model les objets sont des conteneurs pour des parties plutôt que d'hériter de BasePart , ils ne peuvent donc pas se connecter directement à BasePart.Touched ou BasePart.TouchEnded événements.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 .

L'exemple de code suivant connecte tous les BaseParts d'un modèle à plusieurs parties aux événements de collision et suit le nombre total de collisions avec d'autres parties.

Collision de modèle

local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignorer les instances du modèle qui se chevauchent avec lui-même
if otherPart:IsDescendantOf(model) then return end
-- Augmenter le nombre de parties du modèle touchées
numTouchingParts += 1
print(model.Name, "intersected with", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Ignorer les instances du modèle ne se superposant pas avec lui-même
if otherPart:IsDescendantOf(model) then return end
-- Réduire le nombre de parties du modèle touchées
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

Collisions de modèles maillés et solides

MeshPart et PartOperation (parties jointes par modélisation solide ) sont des sous-classe de BasePart , donc les mailles et les parties modélisées solides héritent des mêmes options de événements de collision et de filtrage de collision que les parties régulières.Cependant, puisque les mailles 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 de quelle manière les limites physiques s'alignent avec la représentation visuelle pour la gestion des collisions.

La propriété CollisionFidelity a les options suivantes, du plus bas au plus élevé en termes de fidélité et d'impact sur les performances :

  • Boîte — Crée une boîte de modélisationde collision de bordure, idéale pour les objets petits ou non interactifs.
  • Hull — Génère une coque convexe, appropriée pour les objets avec des indentations ou des cavités moins prononcées.
  • Par défaut — Produit une forme de collision aproche qui prend en charge la concavité, adaptée aux objets complexes avec des besoins d'interaction semi-détailés.
  • Décomposition précise convexe — Offre la fidélité la plus précise, mais n'est toujours pas une représentation 1:1 du visuel.Cette option a le coût de performance le plus élevé et prend plus de temps pour que le moteur se calcule.
Original mesh of castle tower

Pour plus d'informations sur l'impact des performances des options de fidélité de collision et sur la façon de les atténuer, voir optimisation des performances.