Colisões

*Este conteúdo é traduzido por IA (Beta) e pode conter erros. Para ver a página em inglês, clique aqui.

Uma colisão ocorre quando dois objetos 3D entram em contato dentro do mundo 3D. Para um manuseio de colisão personalizado, BasePart tem 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

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 cada parte. Ao considerar o manuseio de colisões em partes, note o seguinte:

  • A propriedade CanTouch de uma parte determina se ela acionará eventos de colisão. Se configurada como false, nem Touched nem TouchEnded serão acionados.
  • A propriedade CanCollide de uma parte afeta se ela colidirá fisicamente com outras partes e causará forças atuando sobre elas. Mesmo que CanCollide esteja desabilitada para uma parte, você pode detectar toque e não-toque através dos eventos Touched e TouchEnded.
  • Os eventos Touched e TouchEnded acionam apenas como resultado de movimento físico, não de mudanças na Position ou CFrame que fazem uma parte intersectar ou parar de intersectar outra parte.
  • A classe de nível superior Terrain herda de BasePart, então você pode atribuir um grupo de colisão a Terrain para determinar se outras BaseParts colidem com voxels de Terreno.

Touched

O evento Touched é acionado quando um BasePart entra em contato com outro, ou com um voxel de Terreno. Ele é acionado apenas como resultado de simulação física e não será acionado quando a Position ou a CFrame da parte for definida explicitamente de tal forma que interseccione 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(). Note que o evento envia o argumento otherPart para a função, indicando a outra parte envolvida na colisão.

Colisão de Parte

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)

Note 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 estabiliza" 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 simples de debounce que impõe um período de "recuperação" por meio de um atributo de instância.

Colisão de Parte com Recuperação

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) -- Definir atributo como verdadeiro
task.wait(COOLDOWN_TIME) -- Esperar pela duração da recuperação
part:SetAttribute("Touched", false) -- Redefinir atributo
end
end
part.Touched:Connect(onTouched)

TouchEnded

O evento TouchEnded é acionado quando toda a extensão da colisão de um BasePart sai dos limites de outro BasePart ou de um voxel preenchido de Terreno. Ele é acionado apenas como resultado de simulação física e não será acionado quando a Position ou a CFrame da parte for definida explicitamente de tal forma que pare de interseccionar 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 o Touched, o evento envia o argumento otherPart para a função, indicando a outra parte envolvida.

Detecção de Não-Colisão

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 numerosos objetos através de grupos de colisão ou pode controlar colisões em uma base parte-para-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 que não colidem passam umas pelas outras completamente, mesmo que ambas as partes tenham sua propriedade CanCollide configurada como true.

No vídeo acima, os objetos giratórios estão em diferentes grupos de colisão, de modo que colidem com objetos de outra cor, mas não com objetos de sua própria cor

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 de Janela ⟩ 3D do Studio.

O editor funciona tanto em Visualização de Lista que favorece o anexamento ao lado esquerdo ou direito do Studio, quanto em uma Visualização de Tabela mais ampla, que favorece o anexo ao topo ou fundo.

Exemplo de Visualização de Lista no Editor de Grupos de Colisão

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 esse 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:

  1. 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 aparecerá em ambas as colunas da visualização de lista ou na coluna esquerda e na linha superior da visualização de tabela.

    Novo grupo adicionado ao Editor de Grupos de Colisão na Visualização de Lista
  2. Repita o processo se necessário, escolhendo um nome único e descritivo para cada grupo. Observe que você pode mudar o nome de um grupo durante o desenvolvimento clicando em seu campo ou selecionando-o e clicando no botão renomear.

    Botão e campo indicados para renomar um grupo no Editor de Grupos de Colisão

Configurar colisões do grupo

Na configuração padrão, os objetos em todos os grupos colidem uns com os outros. Para evitar que objetos em um grupo colidam com objetos em outro grupo, desmarque a caixa na respectiva linha/coluna.

No seguinte exemplo, objetos no grupo Cubes não colidirão com objetos no grupo Doors.

Grupo configurado na Visualização de Lista do Editor de Grupos de Colisão

Atribuir objetos a grupos

Para atribuir objetos a grupos que você registrou através do editor do Studio:

  1. Selecione um ou mais BaseParts que se qualifiquem como parte de um grupo de colisão.

  2. Atribua-os ao grupo clicando no botão para sua linha. Os objetos podem pertencer a apenas um grupo de colisão por vez, portanto, colocá-los em um novo grupo os remove de seu grupo atual.

    Botão de mais indicado no Editor de Grupos de Colisão para adicionar partes selecionadas a um grupo

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

Grupo de colisão escolhido indicado como propriedade CollisionGroup da parte

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 checkpoints em uma experiência 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.

Grupo de Checkpoints configurado para ser não-colidível com o grupo StudioSelectable

Para código de 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 às mecânicas de seleção que os criadores aprenderam a esperar das ferramentas embutidas do Studio.

Raycast de Seleção de Plugin Recomendada

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-para-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 o No Collision constraint. As vantagens incluem:

  • Grupos de colisão e/ou scripts de configuração não são necessários, portanto, você pode facilmente criar e compartilhar modelos com filtragem de colisão personalizada.
  • Partes conectadas não colidirão entre si, mas ainda podem colidir com outros objetos.

Desativar colisões de personagens

Personagens de jogadores do Roblox colidem entre si por padrão. Isso pode levar a gameplays interessantes, mas indesejadas, como personagens pulando uns sobre os outros para alcançar áreas específicas. Se esse comportamento não for desejável, você pode impedir isso através do seguinte Script em ServerScriptService.

Script - Desativar Colisões de Personagens

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 herdar 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 todos os 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.

Colisão de Modelo

local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignorar instâncias do modelo intersectando consigo mesmo
if otherPart:IsDescendantOf(model) then return end
-- Aumentar 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 consigo mesmo
if otherPart:IsDescendantOf(model) then return end
-- Diminuir contagem de partes do modelo tocando
numTouchingParts -= 1
print(model.Name, "não intersectou mais de", 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
end

Colisões de malha e modelo sólido

MeshPart e PartOperation (partes unidas por modelagem sólida) são subclasses de BasePart, portanto, malhas e partes modeladas sólidas 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 sólidas geralmente têm geometrias mais complexas, elas possuem uma propriedade distinta CollisionFidelity que determina quão precisamente os limites físicos se alinham com a representação visual para a manipulação de colisões.

A propriedade CollisionFidelity possui as seguintes opções, em ordem de fidelidade e impacto no desempenho do menor para o maior:

  • 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 menos indentação ou cavidades.
  • 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 da visual. Esta opção tem o custo de desempenho mais caro e leva mais tempo para o mecanismo computar.
Malha original da torre do castelo

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

©2026 Roblox Corporation, Roblox, o logotipo Roblox e Powering Imagination estão entre nossas marcas registradas e não registradas nos EUA e em outros países.