Eu tenho uma lista com coordenadas - saída do algoritmo A * - e gostaria de fazer meus caracteres seguirem suavemente esse caminho com rotações.
Então, eu tenho algo como A e quero obter C
Como posso fazer isso ?
EDITAR
Para me deixar um pouco mais claro:
Estou mais interessado em girar suavemente , já que sei andar de um nó para outro.
EDITAR
Como muitas pessoas acham isso útil (eu também), estou postando um link para a "Natureza do código" de Daniel Shiffman, onde ele discute muitos problemas de IA (e física) de jogos, por exemplo, comportamentos de direção http://natureofcode.com/book/chapter- 6-agentes-autônomos / # chapter06_section8
c#
unity
path-finding
Patryk
fonte
fonte
Respostas:
Se você deseja caminhos suaves em um ambiente baseado em blocos, não há como evitar a aplicação de alguns caminhos nos seus pontos A *. Em seu livro sobre programação de jogos AI, Matt Buckland descreve um algoritmo simples e rápido para suavizar um caminho (basicamente remova todas as arestas que podem ser removidas sem causar interseção com seus obstáculos).
Depois de remover arestas desnecessárias como esta, seu primeiro caso ( A -> B ) é resolvido. A suavização das bordas do gráfico pode ser realizada de várias maneiras. Provavelmente, os splines Hermite funcionariam (dependendo um pouco da densidade do obstáculo e do tamanho do bloco). Outra opção podem ser os comportamentos de direção, nos quais você começa a se dirigir para o próximo ponto de referência, assim que estiver a meio quarteirão de distância do alvo atual (isso realmente depende da velocidade com que o seu "agente" se move / gira).
fonte
Como outros já mencionaram, no segundo caso, você precisará implementar algum tipo de spline ou (na verdade, um ajuste melhor para o seu exemplo) fornecer à unidade algum tipo de comportamento de direção.
No entanto, para o primeiro caso, existe uma solução mais simples e com melhores resultados do que a suavização de caminho. Chama-se Theta * e é uma extensão simples (e relativamente nova) de A * em grades que permite que as unidades se movam em qualquer direção entre os pontos da grade.
Há um bom artigo explicando o Theta * (do qual roubei a imagem acima) aqui
fonte
Para um movimento realista mais humano, tente integrar-se aos comportamentos de direção. (Versão C # do OpenSteer clássico http://sharpsteer.codeplex.com/ ) Você obtém a saída do AStar e deixa o comportamento da direção se preocupar com a movimentação (uma das amostras mostra exatamente como fazer isso, navegue seguindo um caminho)
fonte
No caso de navegação de um ponto a outro, usei a diferença de ângulos (direção atual do jogador vs. direção do ponto atual para o próximo ponto) e depois gradualmente mudei o ângulo para o ângulo final conforme o movimento acontece. Veja este jogo aqui onde os aviões se movem de um ponto para outro, mas a curva não é abrupta, mas, observando atentamente, é possível identificar os pontos do caminho. (o jogo funciona apenas no celular, embora de preferência no iPhone / iPad).
fonte
Eu tive boa sorte com os splines Catmull-Rom (um tipo de spline cúbico, também recomendado por @bummzack). A parte boa disso é que o spline sempre passará pelos pontos de controle, muitos outros não. Implemente algo como isto:
* time é um valor [0,1] entre os pontos de controle 1 e 2.
fonte
A-> B pode ser resolvido usando malhas de navegação em vez de uma grade. Isso implica uma grande mudança na geração de dados de busca de caminhos.
Casos como C e D são apenas um corte de canto: se o personagem está se movendo em um caminho e dentro de um "canto" (célula onde células anteriores, atuais e próximas não estão em uma linha reta), empurre-o na direção da célula anterior e da próxima . O único problema é determinar a distância da posição real (a distância de empurrar). Isso provavelmente exigiria a distância da célula atual como entrada. Algo assim:
fonte