Collisioni

*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.

Una collisione si verifica quando due oggetti 3D entrano in contatto all'interno del mondo 3D. Per una gestione personalizzata delle collisioni, BasePart dispone di 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. È possibile rilevare queste collisioni tramite gli eventi Touched e TouchEnded, che si verificano indipendentemente dal valore della proprietà CanCollide di ciascuna parte. Quando si considera la gestione delle collisioni sulle parti, si noti quanto segue:

  • La proprietà CanTouch di una parte determina se attiva eventi di collisione. Se impostata su false, né TouchedTouchEnded verranno attivati.
  • La proprietà CanCollide di una parte influisce sul fatto che essa collida fisicamente con altre parti e provochi forze che agiscono su di esse. Anche se CanCollide è disabilitata per una parte, è possibile rilevare il contatto e la mancanza di contatto tramite gli eventi Touched e TouchEnded.
  • Gli eventi Touched e TouchEnded si attivano solo a seguito di movimento fisico, non per cambiare Position o CFrame che fa sì che una parte intersechi o smetta di intersecare un'altra parte.
  • La classe di alto livello Terrain eredita da BasePart, quindi puoi assegnare un gruppo di collisione a Terrain per determinare se altre BaseParts collidono con i voxel di Terrain.

Touched

L'evento Touched si attiva quando una BasePart entra in contatto con un'altra, o con un voxel di Terrain. Si attiva solo a seguito di simulazione fisica e non si attiva quando la posizione di Position o CFrame è impostata esplicitamente in modo che intersechi un'altra parte o voxel.

Il seguente modello di codice mostra come l'evento Touched può essere connesso a una funzione onTouched() personalizzata. Nota che l'evento invia l'argomento otherPart alla funzione, indicando l'altra parte coinvolta nella collisione.

Part Collision

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-part. Per evitare di attivare più eventi Touched di quanto necessario, puoi implementare un semplice sistema di debounce che impone un periodo di "raffreddamento" tramite un'attributo istanza.

Part Collision With Cooldown

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) -- Attendere la durata del raffreddamento
part:SetAttribute("Touched", false) -- Ripristina l'attributo
end
end
part.Touched:Connect(onTouched)

TouchEnded

L'evento TouchEnded si attiva quando i confini di collisione di una BasePart escono dai confini di un'altra BasePart o di un voxel di Terrain riempito. Si attiva solo a seguito di simulazione fisica e non si attiva quando la posizione di Position o CFrame è impostata esplicitamente in modo che smetta di intersecare un'altra parte o voxel.

Il seguente modello di codice mostra come l'evento TouchEnded può essere connesso a una funzione onTouchEnded() personalizzata. Come Touched, l'evento invia l'argomento otherPart alla funzione, indicando l'altra parte coinvolta.

Non-Collision Detection

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 tramite gruppi di collisione o puoi controllare le collisioni su base part‑to‑part 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. Le parti all'interno di gruppi non-collisione passano completamente attraverso l'una all'altra, anche se entrambe le parti hanno la loro proprietà CanCollide impostata su true.

Nel video sopra, gli oggetti in rotazione sono in diversi gruppi di collisione in modo tale che collidono con oggetti di un altro colore ma non con oggetti del proprio colore

Puoi facilmente impostare gruppi di collisione tramite l'editor dei Gruppi di Collisione di Studio, accessibile tramite il menu Finestra ⟩ 3D di Studio.

L'editor funziona sia in Elenco View, favorevole al docking sul lato sinistro o destro di Studio, sia in una più ampia Tabella View, che favorisce il docking in alto o in basso.

Esempio di List View nell'editor dei Gruppi di Collisione

Registrazione dei 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 collidono con tutti gli altri oggetti nel gruppo Predefinito.

Per creare un nuovo gruppo di collisione:

  1. 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 vista a elenco, o nella colonna sinistra e nella riga superiore della vista a tabella.

    Nuovo gruppo aggiunto all'editor dei Gruppi di Collisione in List View
  2. 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.

    Pulsante e campo indicati per rinominare un gruppo nell'editor dei Gruppi di Collisione

Configurare le collisioni dei gruppi

Con 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 Cubetti non collidono con gli oggetti nel gruppo Porte.

Gruppo configurato in List View dell'editor dei Gruppi di Collisione

Assegnare oggetti a gruppi

Per assegnare oggetti a gruppi che hai registrato tramite l'editor di Studio:

  1. Seleziona una o più BaseParts che si qualificano come parte di un gruppo di collisione.

  2. Assegna loro il gruppo facendo clic sul pulsante per la sua riga. Gli oggetti possono appartenere solo a un gruppo di collisione alla volta, quindi inserirli in un nuovo gruppo li rimuove dal loro gruppo attuale.

    Pulsante più indicato nell'editor dei Gruppi di Collisione per aggiungere le parti selezionate a un gruppo

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

Gruppo di collisione scelto indicato come proprietà CollisionGroup della parte

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 nella finestra di visualizzazione 3D. Gli oggetti il cui gruppo di collisione assegnato non collide con StudioSelectable verranno ignorati.

Ad esempio, se hai checkpoint in un'esperienza di corsa le cui aree efficaci sono definite da grandi parti trasparenti, puoi assegnarli a un gruppo di collisione Checkpoint e poi rendere quel gruppo non-collidabile con StudioSelectable in modo che non intralcino durante la modifica della geometria del piano sottostante.

Gruppo Checkpoints configurato per essere non-collidabile con il gruppo StudioSelectable

Per il codice dei plugin, è consigliabile assegnare "StudioSelectable" come filtro del gruppo di collisione del tuo RaycastParams quando si trovano parti sotto il cursore. Questo consente ai tuoi plugin di corrispondere alla meccanica di selezione che i creatori hanno imparato a aspettarsi dagli strumenti integrati di Studio.

Raccolta consiglia del plugin

local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Per seguire la convenzione
raycastParams.BruteForceAllSlow = true -- Così le parti con CanQuery di "false" possono essere selezionate
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)

Filtraggio part-to-part

Per evitare collisioni tra due parti specifiche senza impostare gruppi di collisione, come tra la ruota di un veicolo e il suo telaio, prendi in considerazione la No Collision constraint. I vantaggi includono:

  • Non sono necessari gruppi di collisione e/o script di configurazione, quindi puoi facilmente creare e condividere modelli con filtraggio collisioni personalizzato.
  • Le parti collegate non collidano tra loro, ma possono comunque collidere con altri oggetti.

Disabilitare collisioni dei personaggi

I personaggi dei giocatori di Roblox collidono tra loro per impostazione predefinita. Ciò può portare a un gameplay interessante ma indesiderato, come personaggi che saltano sopra l'uno sull'altro per raggiungere aree specifiche. Se questo comportamento è indesiderato, puoi prevenire ciò tramite il seguente Script in ServerScriptService.

Script - Disabilita Collisioni dei Personaggi

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 parti e non ereditano da BasePart, quindi non possono connettersi direttamente agli eventi BasePart.Touched o BasePart.TouchEnded. Per determinare se un modello attiva eventi di collisione, è necessario eseguire un ciclo tra i suoi figli e connettere le funzioni onTouched() e onTouchEnded() personalizzate a ciascuna BasePart.

Il seguente esempio di codice collega tutte le BaseParts di un modello multi-part a eventi di collisione e tiene traccia del numero totale di collisioni con altre parti.

Collisione del Modello

local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignora le istanze del modello che intersecano se stesse
if otherPart:IsDescendantOf(model) then return end
-- Aumenta il conteggio delle parti del modello in contatto
numTouchingParts += 1
print(model.Name, "intersecato con", otherPart.Name, "| Parti del modello in contatto:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Ignora le istanze del modello che non intersecano più se stesse
if otherPart:IsDescendantOf(model) then return end
-- Diminuisci il conteggio delle parti del modello in contatto
numTouchingParts -= 1
print(model.Name, "non più intersecato da", otherPart.Name, "| Parti del modello in contatto:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
end

Collisioni di mesh e modelli solidi

MeshPart e PartOperation (parti unite tramite modellazione solida) sono sottoclassi di BasePart, quindi mesh e parti modellate solidamente ereditano gli stessi eventi di collisione e opzioni di filtraggio delle collisioni come le parti normali. Tuttavia, poiché le mesh e le parti modellate solitamente hanno geometrie più complesse, presentano una particolare 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 limitata, 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 rappresenta comunque in modo 1:1 il visivo. Questa opzione ha il costo di prestazioni più elevato e richiede più tempo per essere elaborata dal motore.
Mesh originale di una torre del castello

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

© 2026 Roblox Corporation. Roblox, il logo Roblox e Powering Imagination sono tra i nostri marchi registrati e non registrati negli Stati Uniti. e altri paesi.