Una collisione si verifica quando due oggetti 3D entrano in contatto all'interno del mondo 3D. Per una gestione personalizzata delle collisioni, BasePart ha un insieme di eventi di collisione e tecniche di filtraggio delle collisioni, in modo da poter controllare quali assemblaggi fisici collidono con altri.
Eventi di collisione
Gli eventi di collisione si verificano quando due BaseParts si toccano o smettono di toccarsi nel mondo 3D. Puoi rilevare queste collisioni attraverso gli eventi Touched e TouchEnded, che si verificano indipendentemente dal valore della proprietà CanCollide di ciascun pezzo. Quando consideri la gestione delle collisioni sui pezzi, nota quanto segue:
- La proprietà CanTouch di un pezzo determina se attiva eventi di collisione. Se impostata su false, né Touched né TouchEnded verranno attivati.
- La proprietà CanCollide di un pezzo influisce su se esso colliderà fisicamente con altri pezzi e causerà forze che agiscono su di essi. Anche se CanCollide è disabilitato per un pezzo, puoi rilevare il contatto e il non contatto attraverso gli eventi Touched e TouchEnded.
- Gli eventi Touched e TouchEnded si attivano solo a seguito di un movimento fisico, non da cambiamenti di Position o CFrame che causano l'intersezione o la cessazione dell'intersezione con un altro pezzo.
Toccato
L'evento Touched si attiva quando un BasePart entra in contatto con un altro, o con un voxel di Terrain. Si attiva solo a seguito di una simulazione fisica e non si attiverà quando la Position o la CFrame del pezzo è impostata esplicitamente in modo tale da intersecare un altro pezzo o voxel.
Il seguente schema di codice mostra come l'evento Touched può essere collegato a una funzione personalizzata onTouched(). Nota che l'evento invia l'argomento otherPart alla funzione, indicando l'altro pezzo coinvolto nella collisione.
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouched(otherPart)
print(part.Name .. " è colliso con " .. otherPart.Name)
end
part.Touched:Connect(onTouched)Nota che l'evento Touched può attivarsi più volte in rapida successione a causa di collisioni fisiche sottili, come quando un oggetto in movimento "si stabilizza" in una posizione di riposo o quando una collisione coinvolge un modello multi‑pezzo. Per evitare di attivare più eventi Touched del necessario, puoi implementare un semplice sistema di debounce che impone un periodo di "raffreddamento" attraverso un attributo d'istanza.
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 .. " è colliso con " .. otherPart.Name)
part:SetAttribute("Touched", true) -- Imposta l'attributo su true
task.wait(COOLDOWN_TIME) -- Attendi la durata del raffreddamento
part:SetAttribute("Touched", false) -- Ripristina l'attributo
end
end
part.Touched:Connect(onTouched)TouchEnded
L'evento TouchEnded si attiva quando l'intero volume di collisione di un BasePart esce dai confini di un altro BasePart o di un voxel di Terrain riempito. Si attiva solo a seguito di una simulazione fisica e non si attiverà quando la Position o la CFrame del pezzo è impostata esplicitamente in modo tale da smettere di intersecare un altro pezzo o voxel.
Il seguente schema di codice mostra come l'evento TouchEnded può essere collegato a una funzione personalizzata onTouchEnded(). Come Touched, l'evento invia l'argomento otherPart alla funzione, indicando l'altro pezzo coinvolto.
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " non sta più toccando " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)Filtraggio delle collisioni
Il filtraggio delle collisioni definisce quali parti fisiche collidono con altre. Puoi configurare il filtraggio per numerosi oggetti attraverso gruppi di collisione oppure puoi controllare le collisioni su base pezzo‑a‑pezzo con istanze di NoCollisionConstraint.
Gruppi di collisione
I gruppi di collisione ti consentono di assegnare BaseParts a gruppi dedicati e specificare se collidono o meno con quelli di altri gruppi. I pezzi all'interno di gruppi non collidenti passano completamente attraverso l'uno e l'altro, anche se entrambi i pezzi hanno la loro proprietà CanCollide impostata su true.
Puoi facilmente impostare i gruppi di collisione attraverso l'editor di Gruppi di Collisione di Studio, accessibile attraverso il menu Finestra ⟩ 3D di Studio.
L'editor funziona sia in Visualizzazione Elenco che favorisce il docking sul lato sinistro o destro di Studio, sia in una più ampia Visualizzazione Tabella, che favorisce il docking in alto o in basso.

Registrare gruppi
L'editor include un gruppo di collisione Predefinito che non può essere rinominato o eliminato. Tutti i BaseParts appartengono automaticamente a questo gruppo predefinito a meno che non siano assegnati a un altro gruppo, il che significa che collideranno con tutti gli altri oggetti nel gruppo Predefinito.
Per creare un nuovo gruppo di collisione:
Fai clic sul pulsante Aggiungi Gruppo nella parte superiore del pannello dell'editor, inserisci un nuovo nome di gruppo e premi Invio. Il nuovo gruppo appare in entrambe le colonne della visualizzazione elenco, o nella colonna sinistra e nella riga superiore della visualizzazione tabella.

Ripeti il processo se necessario, scegliendo un nome unico e descrittivo per ciascun gruppo. Nota che puoi cambiare il nome di un gruppo durante lo sviluppo facendo clic nel suo campo, o selezionandolo e facendo clic sul pulsante rinomina.

Configurare le collisioni di gruppo
Sotto la configurazione predefinita, gli oggetti in tutti i gruppi collidono tra loro. Per impedire che gli oggetti in un gruppo collidano con oggetti in un altro gruppo, deseleziona la casella nella rispettiva riga/colonna.
Nell'esempio seguente, gli oggetti nel gruppo Cubi non collideranno con gli oggetti nel gruppo Porte.

Assegnare oggetti ai gruppi
Per assegnare oggetti ai gruppi che hai registrato tramite l'editor di Studio:
Seleziona uno o più BaseParts che qualificano come parte di un gruppo di collisione.
Assegnali al gruppo facendo clic sul pulsante ⊕ per la sua riga. Gli oggetti possono appartenere a un solo gruppo di collisione alla volta, quindi posizionarli in un nuovo gruppo li rimuove dal loro gruppo attuale.

Una volta assegnato, il nuovo gruppo è riflesso nella proprietà CollisionGroup dell'oggetto.

Gruppo di collisione StudioSelectable
Gli strumenti in Studio utilizzano il sistema di filtraggio delle collisioni per determinare quali oggetti sono candidati per la selezione quando si fa clic nel viewport 3D. Gli oggetti il cui gruppo di collisione assegnato non collida con StudioSelectable verranno ignorati.
Ad esempio, se hai checkpoint in un gioco di corse le cui aree efficaci sono definite da grandi pezzi trasparenti, puoi assegnarli a un gruppo di collisione Checkpoint e poi rendere quel gruppo non collidibile con StudioSelectable in modo che non ostacolino quando stai modificando la geometria sottostante della mappa.

Per il codice del plugin, è consigliato assegnare "StudioSelectable" come filtro del gruppo di collisione dei tuoi RaycastParams quando trovi pezzi sotto il cursore. Questo consente ai tuoi plugin di abbinare le meccaniche di selezione che i creatori hanno imparato a aspettarsi dagli strumenti integrati di Studio.
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Per seguire la convenzione
raycastParams.BruteForceAllSlow = true -- In modo che i pezzi con CanQuery di "false" possano essere selezionati
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)Filtraggio pezzo-a-pezzo
Per prevenire collisioni tra due pezzi specifici senza impostare gruppi di collisione, come tra la ruota di un veicolo e il suo telaio, considera il No Collision vincolo. I vantaggi includono:
- Non sono richiesti gruppi di collisione e/o script di configurazione, quindi puoi facilmente creare e condividere modelli con filtraggio delle collisioni personalizzato.
- I pezzi connessi non collidono tra loro, ma possono comunque collidere con altri oggetti.
Disabilitare le collisioni dei personaggi
I personaggi dei giocatori di Roblox collidono tra loro per impostazione predefinita. Questo può portare a gioco interessante ma indesiderato, come personaggi che saltano l'uno sopra l'altro per raggiungere aree specifiche. Se questo comportamento è indesiderato, puoi prevenirlo attraverso il seguente Script in ServerScriptService.
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
PhysicsService:RegisterCollisionGroup("Personaggi")
PhysicsService:CollisionGroupSetCollidable("Personaggi", "Personaggi", false)
local function onDescendantAdded(descendant)
-- Imposta il gruppo di collisione per qualsiasi parte discendente
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Personaggi"
end
end
local function onCharacterAdded(character)
-- Elabora i discendenti esistenti e nuovi per la configurazione fisica
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- Rileva quando il personaggio del giocatore viene aggiunto
player.CharacterAdded:Connect(onCharacterAdded)
end)Collisioni dei modelli
Gli oggetti Model sono contenitori per pezzi piuttosto che ereditare da BasePart, quindi non possono collegarsi direttamente agli eventi BasePart.Touched o BasePart.TouchEnded. Per determinare se un modello attiva eventi di collisione, devi scorrere i suoi figli e collegare le funzioni personalizzate onTouched() e onTouchEnded() a ciascun BasePart figlio.
Il seguente esempio di codice collega tutti i BaseParts di un modello multi‑pezzo agli eventi di collisione e tiene traccia del numero totale di collisioni con altri pezzi.
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignora le istanze del modello che si intersecano con se stesse
if otherPart:IsDescendantOf(model) then return end
-- Aumenta il conteggio dei pezzi del modello che toccano
numTouchingParts += 1
print(model.Name, "intersecato con", otherPart.Name, "| Pezzi del modello che toccano:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Ignora le istanze del modello che smettono di intersecarsi con se stesse
if otherPart:IsDescendantOf(model) then return end
-- Diminuisci il conteggio dei pezzi del modello che toccano
numTouchingParts -= 1
print(model.Name, "non intersecato più da", otherPart.Name, "| Pezzi del modello che toccano:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
endCollisioni di Mesh e Modelli Solidi
MeshPart e PartOperation (pezzi uniti tramite modellazione solida) sono sottoclassi di BasePart, quindi le mesh e i pezzi modellati solidamente ereditano gli stessi eventi di collisione e opzioni di filtraggio delle collisioni come i pezzi normali. Tuttavia, poiché le mesh e i pezzi modellati solidamente hanno solitamente geometrie più complesse, hanno una distintiva proprietà CollisionFidelity che determina quanto precisamente i confini fisici si allineano con la rappresentazione visiva per la gestione delle collisioni.
La proprietà CollisionFidelity ha le seguenti opzioni, in ordine di fedeltà e impatto sulle prestazioni dal più basso al più alto:
- Box — Crea una scatola di collisione di delimitazione, ideale per oggetti piccoli o non interattivi.
- Hull — Genera un involucro convesso, adatto per oggetti con indentazioni o cavità meno pronunciate.
- Default — Produce una forma di collisione approssimativa che supporta la concavità, adatta per oggetti complessi con esigenze di interazione semi-dettagliate.
- PreciseConvexDecomposition — Offre la massima precisione, ma non una rappresentazione 1:1 del visivo. Questa opzione ha il costo di prestazioni più elevato e richiede più tempo per essere calcolata dal motore.

Per ulteriori informazioni sull'impatto delle prestazioni delle opzioni di fedeltà di collisione e su come mitigarle, vedere Ottimizzazione delle prestazioni.