Como fazer meus personagens ficarem tranqüilos enquanto andam em um caminho (lista de coordenadas)?


15

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

insira a descrição da imagem aqui

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


O pathfinding não está embutido no Unity?
precisa saber é o seguinte

@ Tom Bem, sim, mas eu tenho minha versão implementada de qualquer maneira. O objetivo desta pergunta é obter curvas suaves (rotações) enquanto caminha pelo caminho.
Patryk

3
Um bom termo no Google a este respeito é 'Comportamento direcção' :)
Roy T.

3
@RoyT. Claro ! Fui ler este algumas semanas e já esqueci: / Este é um ótimo artigo sobre seguinte caminho com a matemática incrível + explicação física natureofcode.com
Patryk

11
Eu só queria agradecer a @ Patryk pelo link - parece realmente informativo e tenho procurado um bom recurso sobre o comportamento da direção.
Christian

Respostas:


7

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


9

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.

Teta * vs. suavização de caminho

Há um bom artigo explicando o Theta * (do qual roubei a imagem acima) aqui


2

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)


1

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


Foi exatamente isso que acabei fazendo.
Patryk

1

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:

t    = <time*>
t12  = t + 1.0
t23  = t
t34  = t - 1.0
t123 = (t + 1.0) / 2.0
t234 = t / 2

c1 = controlpoint[0];
c2 = controlpoint[1];
c3 = controlpoint[2];
c4 = controlpoint[3];

l12 = lerp(c1, c2, t12);
l23 = lerp(c2, c3, t23);
l34 = lerp(c3, c4, t34);
position = lerp(lerp(l12, l23, t123), lerp(l23, l34, t234), t);

* time é um valor [0,1] entre os pontos de controle 1 e 2.


0

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:

push_dir = average( prevcell.pos, nextcell.pos ) - curcell.pos;
push_dist = cell_half_width - distance( char.pos, curcell.pos );
char.pos += push_dir * push_dist;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.