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 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 a agir 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 causam uma parte a 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 os voxels de Terreno.

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.

Colisão de Parte
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.

Colisão de Parte Com Cooldown
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 todos os limites de colisão de um BasePart saem 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.

Detecção de Não-Colisão
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. Grupos de colisão são criados e configurados com base em Workspace ou WorldModel.

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

Registrar grupos

Workspace armazena seu próprio estado configurável de grupos de colisão. Além disso, qualquer WorldModel pode optar por usar seus próprios grupos de colisão para consultas.

O editor inclui um grupo de colisão Padrão que não pode ser renomeado ou excluído. Todas as BaseParts pertencem automaticamente a este grupo padrão, a menos que sejam atribuídas a outro grupo, o que significa que colidirão com todos os outros objetos no grupo Padrão.

Para criar um novo grupo de colisão:

  1. Por padrão, os grupos são registrados em Workspace, mas se você tiver pelo menos um WorldModel em seu lugar, um menu suspenso de seleção aparecerá na parte superior do editor de grupos de colisão. Use o menu suspenso para configurar grupos de colisão em diferentes instâncias de WorldModel.

    Workspace indicado como o mundo atualmente ativo do editor de grupos de colisão

    Para qualquer WorldModel, você pode ativar Usar grupos de colisão do Workspace para fazê-lo usar grupos de colisão de Workspace para suas consultas.

    Caixa de seleção indicada para alternar a propriedade UseWorkspaceCollisionGroups de um WorldModel
  2. 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.

    Novo grupo adicionado ao Editor de Grupos de Colisão na Visualização de Lista
  3. 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 renomear um grupo no Editor de Grupos de Colisão

Configurar colisões de grupos

Na 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.

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 uma 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. 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.

    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 a propriedade CollisionGroup da parte

Grupo 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.

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

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.

Raycast de Seleção de Plugin Recomendado
local UserInputService = game:GetService("UserInputService")
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 podem 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.

Script - Desativar Colisões de Personagens
local Players = game:GetService("Players")
workspace:RegisterCollisionGroup("Characters")
workspace: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 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 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.

Colisão de Modelo
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignorar instâncias do modelo intersectando consigo mesmas
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 consigo mesmas
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
end

Colisõ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 as mesmas opções de eventos de colisão e 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.
Malha original da torre do castelo

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.

©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.