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 manipulação de colisão personalizada, BasePart tem um conjunto de eventos de colisão e técnicas de filtragem de colisão, para que você possa controlar quais assemblagens físicas colidem com outras.

Eventos de colisão

Os eventos de colisão ocorrem quando dois pararem de se tocar no mundo 3D.Você pode detectar essas colisões através dos eventos Touched e TouchEnded, que ocorrem independentemente do valor da propriedade da parte CanCollide.Ao considerar o manuseio de colisão em peças, observe o seguindo:

  • A propriedade de uma peça determina se ela gera eventos de colisão. Se definida como , nem nem serão Iniciar / executar.
  • A propriedade de uma peça afeta se ela vai fisicamente colidir com outras peças e causar forças para agir sobre elas.Mesmo que CanCollide seja desativado para uma parte, você pode detectar toque e não toque através de Touched e TouchEnded eventos.
  • Os eventos Touched e TouchEnded só são acionados como resultado do movimento físico physical , não de mudanças Position ou CFrame que causem 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 outros BaseParts colidem com Terrain voxels.

Tocado

O evento Touched ocorre quando um BasePart entra em contato com outro, ou com um voxel de Terreno.Ele só dispara como resultado de simulação física e não dispara quando a peça Position ou CFrame for explicitamente definida para intersectar outra peça 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 à 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 .. " collided with " .. otherPart.Name)
end
part.Touched:Connect(onTouched)

Observe que o evento Touched pode disparar várias vezes em rápida sucessão com base em colisões físicas sutis, como quando um objeto em movimento "se instala" em uma posição de repouso ou quando uma colisão envolve um modelo de múltiplas partes.Para evitar disparar mais eventos Touched do que o necessário, você pode implementar um sistema simples de debounce que impõe um período de "resfriamento" através de um atributo da instância.

Colisão de Parte com Tempo de Espera

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 .. " collided with " .. otherPart.Name)
part:SetAttribute("Touched", true) -- Defina o atributo para verdadeiro
task.wait(COOLDOWN_TIME) -- Espere pela duração de espera
part:SetAttribute("Touched", false) -- Atributo de redefinição
end
end
part.Touched:Connect(onTouched)

ToqueTerminado

O evento ocorre quando toda a área de colisão de um sai dos limites de outro ou um voxel de terreno preenchido.Ele só dispara como resultado de simulação física e não dispara quando a peça Position ou CFrame for explicitamente definida para parar de intersectar outra peça ou voxel.

O seguinte padrão de código mostra como o evento TouchEnded pode ser conectado a uma função personalizada onTouchEnded().Como Touched , o evento envia o argumento otherPart à 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 .. " is no longer touching " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)

Filtro de colisão

A colisão filtragem define quais partes físicas colidem com outras.Você pode configurar filtragem para inúmeros objetos através de grupos de colisão ou você pode controlar colisões em uma base de parte para parte com instâncias.

Grupos de colisão

A colisão grupos permite que você atribua BaseParts a grupos dedicados e especifique se eles colidem ou não com os de outros grupos.Peças dentro de grupos não colidentes passam umas pelas outras completamente, mesmo que ambas as peças tenham seu conjunto de propriedades CanCollide definido como true.

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

Você pode facilmente configurar grupos de colisão através do Editor de Grupos de Colisão do Studio, acessível clicando no botão Grupos de Colisão na aba Modelo da barra de ferramentas.

Collision Groups tool indicated in Model tab of Studio

O editor funciona em qualquer uma das seguintes opções: Visualização em Lista , que favorece acoplamento para o lado esquerdo ou direito do Studio, ou em uma visualização mais ampla Tabela , que favorece o acoplamento para a parte superior ou inferior.

List View example in Collision Groups Editor

Registrar grupos

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

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 aparece em ambas as colunas da verem lista ou em ambas as colunas da verde tabela.

    New group added to Collision Groups Editor in List View
  2. 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 .

    Button and field indicated for renaming a group in the Collision Groups Editor

Configurar colisões de grupo

Na configuração padrão, 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 Cubos não colidirão com objetos no grupo Portas .

Group configured in List View of Collision Groups Editor

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 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 de uma vez, então colocá-los em um novo grupo os remove de seu grupo atual.

    Plus button indicated in Collision Groups Editor for adding selected parts to a group

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

Chosen collision group indicated as the part's CollisionGroup property

grupode colisão selecionável do Studio

Ferramentas no Studio usam o sistema de filtragem de colisão para determinar quais objetos são candidatos para seleção ao clicar na janela de visualização 3D.Objetos cujo grupo de colisão designado não faça não colidir com StudioSelectable serão ignorados.

Por exemplo, se você tiver pontos de verificação em uma experiência de corrida cujas áreas eficazes sejam definidas por grandes peças transparentes, você pode atribuí-las a um grupo de colisão de pontos de verificação e, em seguida, tornar esse grupo não colidível com StudioSelectable para que eles não fiquem no caminho quando você estiver editando a geometria do mapa subjacente.

Checkpoints group configured to be non-collidable with StudioSelectable group

Para código de plugin, é recomendado que você atribua "StudioSelectable" como filtro de grupo de colisão de seu RaycastParams quando encontrar peças sob o cursor.Isso permite que seus plugins correspondam às mecânicas de seleção que os criadores aprenderam a esperar das ferramentas integradas do Studio.

Recomendado Raycast de Seleção de Plugin

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)

Filtro de parte a parte

Para evitar colisões entre duas peças específicas sem configurar grupos de colisão, como entre a roda de um veículo e seu chassi, considere a restrição Sem Colisão.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.
  • Peças conectadas não colidirão umas com as outras, mas ainda podem colidir com outros objetos.

Desabilitar colisões de personagens

Os personagens de jogadores do Roblox colidem uns com os outros por padrão.Isso pode levar a um jogabilidadeinteressante, mas não intencional, como personagens pulando um sobre o outro para alcançar áreas específicas.Se esse comportamento for indesejável, você pode impedi-lo através do seguinte Script em ServerScriptService .

Script - Desabilitar colisões de personagens

local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
local CollisionGroupName = "Characters"
PhysicsService:RegisterCollisionGroup(CollisionGroupName)
PhysicsService:CollisionGroupSetCollidable(CollisionGroupName, CollisionGroupName, false)
local function setCollisionGroup(model)
-- Aplique o grupo de colisão a todas as peças existentes no modelo
for _, descendant in model:GetDescendants() do
if descendant:IsA("BasePart") then
descendant.CollisionGroup = CollisionGroupName
end
end
end
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
setCollisionGroup(character)
end)
-- Se o jogador já tem um personagem, aplique o grupo de colisão imediatamente
if player.Character then
setCollisionGroup(player.Character)
end
end)

Colisões de modelo

Model objetos são contêineres para peças em vez de herdar de BasePart , portanto, eles não podem se conectar diretamente a BasePart.Touched ou BasePart.TouchEnded eventos.Para determinar se um modelo gera eventos de colisão, você precisa percorrer seus filhos e conectar as funções personalizadas onTouched() e onTouchEnded() à cada filho BasePart .

O seguinte exemplo de código conecta todos os BaseParts de um modelo de várias 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 com ele mesmo
if otherPart:IsDescendantOf(model) then return end
-- Aumentar o número de peças de modelo tocando
numTouchingParts += 1
print(model.Name, "intersected with", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Ignorar instâncias do modelo que não se intersectam com ele mesmo
if otherPart:IsDescendantOf(model) then return end
-- Diminuir o número de peças de modelo tocando
numTouchingParts -= 1
print(model.Name, "un-intersected from", otherPart.Name, "| Model parts touching:", 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 modelo de malha e sólido

MeshPart e PartOperation (peças juntadas por modelagem sólida ) são subclases de BasePart , portanto, malhas e peças modeladas sólidas herdam as mesmas opções de colisão e filtragem de colisão que as peças regulares.No entanto, já que malhas e peças modeladas sólidas geralmente têm geometrias mais complexas, elas têm uma propriedade distinta CollisionFidelity que determina com que precisão os limites físicos se alinham com a representação visual para o manuseio de colisões.

A propriedade CollisionFidelity tem as seguintes opções, em ordem de fidelidade e impacto de desempenho, da menor para a maior:

  • Caixa — Cria uma caixa de colisão de limite, ideal para objetos pequenos ou não interativos.
  • Casca — Gera uma casca côncava, adequada para objetos com menos depressões ou cavidades pronunciadas.
  • Padrão — Produz uma forma de colisão aproximada que suporta a concavidade, adequada para objetos complexos com necessidades de interação semi-detalhadas.
  • PrecisaConvexDecomposition — Oferece a fidelidade mais precisa, mas ainda não é uma representação 1:1 do visual.Essa opção tem o custo de desempenho mais caro e leva mais tempo para o motor processar.
Original mesh of castle tower

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.