Como fazer o jogador deslizar suavemente contra o terreno

11

diagrama

Estou fazendo um jogo isométrico. Quando o jogador tenta andar diagonalmente contra uma parede, quero que deslizem suavemente sobre ela, para que qualquer parte do movimento seja legal e usada, e qualquer coisa na direção do normal é jogada fora. As paredes podem ser de qualquer ângulo, não apenas verticais ou horizontais, e o player possui 360 movimentos.

Sinto que estou quase lá, mas não consigo colocar a última peça no lugar.

Atualização: boas notícias a todos! Eu tenho isso funcionando. Mas ... estou um pouco confuso sobre o que deveria estar normalizando e o que não. O normal só precisa ser um vetor de unidade, certo? mas então eu estou misturando isso com a minha entrada, então estou normalizando isso - estou errado?

A propósito, também descobri que preciso empurrar o player 1 pixel na direção normal, para que eles não fiquem presos às coisas - funciona bem.

Iain
fonte

Respostas:

13

Apenas projete seu vetor de movimento no plano normal e subtraia o resultado do seu vetor de movimento.

Vector undesiredMotion = normal * (dotProduct(input, normal));
Vector desiredMotion = input - undesiredMotion;

Algo assim de qualquer maneira. Embora em seu diagrama adorável a entrada pareça estar longe da parede, estou um pouco confuso.

Chris Howe
fonte
desculpe, ele deveria estar na frente de uma parede vertical lá. desenho terrível
Iain
1
Estou um pouco confuso sobre o produto escalar. O produto escalar não é escalar?
Iain
1
Sim, mas você o multiplica pelo normal (um vetor) para obter o vetor do seu movimento indesejado. Um vetor (x, y, z) multiplicado pelo escalar s obtém o vetor (sx, sy, sz).
Chris Howe
Feito, alterou as variáveis ​​para coincidir com o diagrama. :)
Chris Howe
@Iain Estou realmente tentando entender como usar essa resposta, mas não consigo entender. Quando crio esse código exato, obtenho desiredMotionresultados realmente estranhos . Você já conseguiu isso funcionando?
teste
1

Embora seja simples remover o componente do movimento que está na direção normal, pode ser adequado à sua jogabilidade girar o vetor de movimento. Por exemplo, em um jogo de ação na terceira pessoa, pode ser fácil ficar um pouco pendurado nas paredes e em outros limites, para que você possa adivinhar o que o jogador pretende.

// assume that 'normal' is unit length
Vector GetDesired(Vector input, Vector normal) {
   // tune this to get where you stop when you're running into the wall,
   // vs. bouncing off of it
   static float k_runningIntoWallThreshold = cos(DEG2RAD(45));

   // tune this to "fudge" the "push away" from the wall
   static float k_bounceFudge = 1.1f;

   // normalize input, but keep track of original size
   float inputLength = input.GetLength();
   input.Scale(1.0f / inputLength);

   float dot = DotProduct(input, normal);

   if (dot < 0)
   {
      // we're not running into the wall
      return input;
   }
   else if (dot < k_runningIntoWallThreshold)
   {
      Vector intoWall = normal.Scale(dot);
      intoWall.Scale(k_bounceFudge);

      Vector alongWall = (input - intoWall).Normalize();
      alongWall.Scale(inputLength);

      return alongWall;
   }
   else
   {
      // we ran "straight into the wall"
      return Vector(0, 0, 0);
   }
}
traço-tom-bang
fonte
Agradável. Mas se você escalar por um fator de fudge, isso o faz esbarrar na parede e deslizar ao longo dela, ou é apenas um caso de aprimorá-la?
Chris Howe
Meu pensamento é que você o ajusta para parecer bem; certamente, se for muito grande, parecerá que você está pulando, mas se for sutil o suficiente, evitará que você fique pendurado em pequenas curvas na superfície.
dash-tom-bang