Uma colisão ocorre quando dois objetos 3D entram em contato dentro do mundo 3D. Para um manuseio de colisão personalizado, BasePart possui um conjunto de eventos de colisão e técnicas de filtragem de colisão, para que você possa controlar quais montagens físicas colidem com outras.
Eventos de colisão
Os eventos de colisão ocorrem quando dois BaseParts tocam ou param de tocar no mundo 3D. Você pode detectar essas colisões através dos eventos Touched e TouchEnded, que ocorrem independentemente do valor da propriedade CanCollide de qualquer parte. Ao considerar o manuseio de colisão em partes, observe o seguinte:
- A propriedade CanTouch de uma parte determina se ela aciona eventos de colisão. Se definida como false, nem Touched nem TouchEnded serão acionados.
- A propriedade CanCollide de uma parte afeta se ela irá fisicamente colidir com outras partes e causar forças sobre elas. Mesmo que CanCollide esteja desativado para uma parte, você pode detectar toque e não-toque através dos eventos Touched e TouchEnded.
- Os eventos Touched e TouchEnded só são acionados como resultado de movimento físico, não de mudanças em Position ou CFrame que fazem uma parte intersectar ou parar de intersectar outra parte.
Tocado
O evento Touched é acionado quando um BasePart entra em contato com outro, ou com um voxel de Terreno. Ele só é acionado como resultado de simulação física e não será acionado quando a Position ou CFrame da parte for explicitamente definida de forma que intersecte outra parte ou voxel.
O seguinte padrão de código mostra como o evento Touched pode ser conectado a uma função personalizada onTouched(). Observe que o evento envia o argumento otherPart para a função, indicando a outra parte envolvida na colisão.
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouched(otherPart)
print(part.Name .. " colidiu com " .. otherPart.Name)
end
part.Touched:Connect(onTouched)Observe que o evento Touched pode ser acionado várias vezes em rápida sucessão com base em colisões físicas sutis, como quando um objeto em movimento "se acomoda" em uma posição de descanso ou quando uma colisão envolve um modelo de múltiplas partes. Para evitar acionar mais eventos Touched do que o necessário, você pode implementar um sistema de debounce simples que impõe um período de "cooldown" através de um atributo de instância.
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 .. " colidiu com " .. otherPart.Name)
part:SetAttribute("Touched", true) -- Defina o atributo como verdadeiro
task.wait(COOLDOWN_TIME) -- Aguarde a duração do cooldown
part:SetAttribute("Touched", false) -- Redefina o atributo
end
end
part.Touched:Connect(onTouched)Toque Finalizado
O evento TouchEnded é acionado quando todo o limite de colisão de um BasePart sai dos limites de outro BasePart ou de um voxel de Terreno preenchido. Ele só é acionado como resultado de simulação física e não será acionado quando a Position ou CFrame da parte for explicitamente definida de forma que pare de intersectar outra parte ou voxel.
O seguinte padrão de código mostra como o evento TouchEnded pode ser conectado a uma função personalizada onTouchEnded(). Assim como Touched, o evento envia o argumento otherPart para a função, indicando a outra parte envolvida.
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " não está mais tocando " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)Filtragem de colisão
A filtragem de colisão define quais partes físicas colidem com outras. Você pode configurar a filtragem para vários objetos através de grupos de colisão ou pode controlar colisões em uma base parte-a-parte com instâncias de NoCollisionConstraint.
Grupos de colisão
Os grupos de colisão permitem que você atribua BaseParts a grupos dedicados e especifique se colidem ou não com aqueles em outros grupos. Partes dentro de grupos não-colidantes passam completamente umas pelas outras, mesmo que ambas as partes tenham sua propriedade CanCollide definida como true.
Você pode configurar facilmente grupos de colisão através do editor de Grupos de Colisão do Studio, acessível através do menu Janela ⟩ 3D do Studio.
O editor funciona em Visualização de Lista, que favorece o anexamento ao lado esquerdo ou direito do Studio, ou em uma Visualização de Tabela mais ampla, que favorece o anexo ao topo ou à parte inferior.

Registrar grupos
O editor inclui um grupo de colisão Padrão que não pode ser renomeado ou excluído. Todos os BaseParts pertencem automaticamente a este grupo padrão, a menos que sejam atribuídos a outro grupo, o que significa que eles colidirão com todos os outros objetos no grupo Padrão.
Para criar um novo grupo de colisão:
Clique no botão Adicionar Grupo na parte superior do painel do editor, insira um novo nome de grupo e pressione Enter. O novo grupo aparece em ambas as colunas da visualização de lista, ou na coluna esquerda e na linha superior da visualização de tabela.

Repita o processo se necessário, escolhendo um nome único e descritivo para cada grupo. Observe que você pode alterar o nome de um grupo durante o desenvolvimento clicando em seu campo ou selecionando-o e clicando no botão renomear.

Configurar colisões de grupos
Sob a configuração padrão, objetos em todos os grupos colidem entre si. Para evitar que objetos em um grupo colidam com objetos em outro grupo, desmarque a caixa na respectiva linha/coluna.
No exemplo a seguir, objetos no grupo Cubes não colidirão com objetos no grupo Doors.

Atribuir objetos a grupos
Para atribuir objetos a grupos que você registrou através do editor do Studio:
Selecione uma ou mais BaseParts que se qualifiquem como parte de um grupo de colisão.
Atribua-os ao grupo clicando no botão ⊕ para sua linha. Objetos podem pertencer a apenas um grupo de colisão por vez, então colocá-los em um novo grupo os remove de seu grupo atual.

Uma vez atribuídos, o novo grupo é refletido na propriedade CollisionGroup do objeto.

Grupo de colisão StudioSelectable
As ferramentas no Studio usam o sistema de filtragem de colisão para determinar quais objetos são candidatos à seleção ao clicar na visualização 3D. Objetos cujo grupo de colisão atribuído não colide com StudioSelectable serão ignorados.
Por exemplo, se você tiver pontos de verificação em um jogo de corrida cujas áreas efetivas são definidas por grandes partes transparentes, você pode atribuí-los a um grupo de colisão Checkpoints e, em seguida, tornar esse grupo não colidível com StudioSelectable para que não atrapalhem ao editar a geometria do mapa subjacente.

Para o código do plugin, é recomendável que você atribua "StudioSelectable" como o filtro de grupo de colisão de seu RaycastParams ao encontrar partes sob o cursor. Isso permite que seus plugins correspondam à mecânica de seleção que os criadores aprenderam a esperar das ferramentas integradas do Studio.
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Para seguir a convenção
raycastParams.BruteForceAllSlow = true -- Para que partes com CanQuery de "false" possam ser selecionadas
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)Filtragem parte-a-parte
Para evitar colisões entre duas partes específicas sem configurar grupos de colisão, como entre a roda de um veículo e seu chassi, considere a No Collision constraint. As vantagens incluem:
- Grupos de colisão e/ou scripts de configuração não são necessários, então você pode facilmente criar e compartilhar modelos com filtragem de colisão personalizada.
- Partes conectadas não colidirão entre si, mas ainda poderão colidir com outros objetos.
Desativar colisões de personagens
Os personagens dos jogadores do Roblox colidem entre si por padrão. Isso pode levar a jogabilidade interessante, mas indesejada, como personagens pulando uns sobre os outros para alcançar áreas específicas. Se esse comportamento for indesejável, você pode evitá-lo através do seguinte Script em ServerScriptService.
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:CollisionGroupSetCollidable("Characters", "Characters", false)
local function onDescendantAdded(descendant)
-- Defina o grupo de colisão para qualquer parte descendente
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Characters"
end
end
local function onCharacterAdded(character)
-- Processar descendentes existentes e novos para configuração de física
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- Detectar quando o personagem do jogador é adicionado
player.CharacterAdded:Connect(onCharacterAdded)
end)Colisões de modelos
Objetos Model são contêineres para partes em vez de herdarem de BasePart, então eles não podem se conectar diretamente aos eventos BasePart.Touched ou BasePart.TouchEnded. Para determinar se um modelo aciona eventos de colisão, você precisa percorrer seus filhos e conectar as funções personalizadas onTouched() e onTouchEnded() a cada BasePart filho.
O seguinte exemplo de código conecta todas as BaseParts de um modelo de múltiplas partes a eventos de colisão e rastreia o número total de colisões com outras partes.
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignorar instâncias do modelo intersectando com ele mesmo
if otherPart:IsDescendantOf(model) then return end
-- Aumentar a contagem de partes do modelo tocando
numTouchingParts += 1
print(model.Name, "intersectou com", otherPart.Name, "| Partes do modelo tocando:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Ignorar instâncias do modelo não intersectando com ele mesmo
if otherPart:IsDescendantOf(model) then return end
-- Diminuir a contagem de partes do modelo tocando
numTouchingParts -= 1
print(model.Name, "não intersectou mais com", otherPart.Name, "| Partes do modelo tocando:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
endColisões de malha e modelo sólido
MeshPart e PartOperation (partes unidas por modelagem sólida) são subclasses de BasePart, então malhas e partes modeladas de forma sólida herdam os mesmos eventos de colisão e opções de filtragem de colisão que partes regulares. No entanto, como malhas e partes modeladas de forma sólida geralmente têm geometrias mais complexas, elas possuem uma propriedade distintiva CollisionFidelity que determina quão precisamente os limites físicos se alinham com a representação visual para o manuseio de colisão.
A propriedade CollisionFidelity tem as seguintes opções, em ordem de fidelidade e impacto no desempenho do mais baixo para o mais alto:
- Caixa — Cria uma caixa de colisão delimitadora, ideal para objetos pequenos ou não interativos.
- Casco — Gera um casco convexo, adequado para objetos com indentação ou cavidades menos pronunciadas.
- Padrão — Produz uma forma de colisão aproximada que suporta concavidade, adequada para objetos complexos com necessidades de interação semi-detalhadas.
- Decomposição Convexa Precisa — Oferece a fidelidade mais precisa, mas ainda não uma representação 1:1 do visual. Esta opção tem o custo de desempenho mais caro e leva mais tempo para o motor calcular.

Para mais informações sobre o impacto no desempenho das opções de fidelidade de colisão e como mitigá-las, veja Otimização de desempenho.