O evento Unity's on collision fornece um objeto Collision que fornece algumas informações sobre a colisão que ocorreu (incluindo uma lista de ContactPoints com normais de ocorrência).
Mas o que você não obtém são normais de superfície para o colisor atingido. Aqui está uma captura de tela para ilustrar. A linha vermelha é de ContactPoint.normal
e a linha azul é de RaycastHit.normal
.
Essa é uma instância de informações ocultas do Unity para fornecer uma API simplificada? Ou as técnicas padrão de detecção de colisão em tempo real 3D simplesmente não coletam essas informações?
E para a segunda parte da pergunta, qual é a maneira certa e relativamente eficiente de obter uma superfície normal para uma colisão?
Eu sei que o raycasting fornece normais de superfície, mas parece que eu preciso fazer vários raycasts para fazer isso em todos os cenários (talvez uma combinação de ponto de contato / normal perca o colisor no primeiro elenco ou talvez você precise fazer uma média de tudo normais dos pontos de contato para obter o melhor resultado).
Meu método atual:
Faça backup do
Collision.contacts[0].point
seu hit normalRaycast abaixo o hit negado normal para
float.MaxValue
, emCollision.collider
Se isso falhar, repita as etapas 1 e 2 com a função normal não negada.
Se isso falhar, tente as etapas 1 a 3 com
Collision.contacts[1]
Repita 4 até obter êxito ou até que todos os pontos de contato tenham se esgotado.
Desista, volte
Vector3.zero
.
Isso parece pegar tudo, mas todos esses raycasts me deixam enjoado e não sei como testar se isso funciona em casos suficientes. Existe uma maneira melhor?
EDITAR Se realmente é assim que as coisas acontecem com a colisão 3D, uma visão geral do porquê, no caso geral, seria tão bem-vinda quanto algo específico do Unity.
fonte
Respostas:
Realmente é assim que as coisas acontecem com a colisão. Não apenas 3D, mas também 2D. Veja o seguinte exemplo:
Os AABBs verde e vermelho estão colidindo e o coletor de contato é a área azul. Os pontos de contato estarão na área azul em algum lugar (exatamente onde pode variar com o algoritmo, mas os cantos onde o azul / vermelho / verde se encontra são ideais).
Que superfície normal deve ser devolvida? A borda superior do AABB vermelho ou a borda esquerda? Se a caixa verde estiver caindo, talvez possamos adivinhar razoavelmente a borda superior. se estiver se movendo para a direita, talvez possamos adivinhar razoavelmente a borda esquerda. E se estivesse se movendo para baixo e para a direita? Tomamos o eixo de menor penetração? O eixo de velocidade de maior velocidade? Alguma heurística de ambos? E se as caixas colidissem exatamente nos cantos?
Estenda isso para uma superfície 3D complexa, potencialmente composta de 100s de tris / faces. Você ainda terá apenas um pequeno número de pontos de contato ideais. Que superfície normal deve ser devolvida? A superfície média normal em toda a malha dupla (o que não faz sentido para a maioria dos objetos)? Os pontos diretamente "embaixo" dos cantos da caixa de colisão (que não estão bem definidos para a maioria das outras formas)? Você tenta encontrar a face mais próxima dos pontos de contato gerados (o que exigiria uma segunda passagem, já que os pontos de contato não são calculados diretamente de nenhuma face da malha)? Se você encontrar a face mais próxima, considera a normal da face ou interpola os vértices da face no ponto de contato para obter a normal correta para objetos "suaves"?
Realmente, o principal problema é que os pontos de contato não são todos . Em muitos casos, isso seria um conjunto infinito de pontos, afinal. São apenas alguns pontos bem distribuídos que tornam razoavelmente possível aproximar a reação física aplicando forças nesses pontos para empurrar os objetos em colisão de maneira reaslítica. Os pontos / locais específicos do contato real com o objeto são abstraídos por trás de um modelo matemático simplificado. Portanto, a idéia de uma superfície específica normal de contato simplesmente não faz muito sentido no caso geral.
Obviamente, com restrições e limitações mais específicas em seus objetos, mundo e movimento, você pode criar algoritmos de colisão alternativos que podem falar sobre a superfície normal. No caso 2D acima, se assumirmos que as caixas nunca giram e que sabemos a velocidade relativa e a última posição de cada uma delas, poderia usar a detecção de colisão contínua para descobrir exatamente quando elas colidiriam e quais recursos colidiram, fornecendo-nos o característica exata onde ocorreu a colisão, que poderia então ser usada como um contato / colisão / superfície normal. Os jogos de plataformas são construídos inteiramente com base em suposições e truques especiais (é por isso que usar uma biblioteca de física geral como Box2D ou Havok ou a luz nunca produz o tipo de controle preciso e preciso que você encontra em plataformas clássicas como Mario ou Sonic; eu não faria isso quer dizer '
Bibliotecas gerais de física newtoniana, como a usada no Unity3D, não podem fazer esse tipo de simplificação e suposição. Portanto, você não obtém normais de superfície de colisão, obtém um coletor de contato, geralmente simplificado até os pontos de contato, e é isso.
fonte