Cómo hacer que el jugador se deslice suavemente contra el terreno


11

diagrama

Estoy haciendo un juego isométrico. Cuando el jugador intenta caminar diagonalmente hacia una pared, quiero que se deslicen suavemente sobre ella, de modo que se use cualquier parte del movimiento que sea legal, y se deseche cualquier cosa en la dirección de lo normal. Las paredes pueden ser de cualquier ángulo, no solo verticales u horizontales, y el jugador tiene movimiento 360.

Siento que casi estoy allí, pero no puedo poner la última pieza en su lugar.

Actualización: ¡buenas noticias para todos! Lo tengo funcionando. Pero ... estoy un poco confundido sobre lo que debería normalizar y lo que no. Lo normal solo necesita ser un vector unitario, ¿verdad? pero luego estoy mezclando eso con mi entrada, así que estoy normalizando eso, ¿me equivoco?

Por cierto, también descubrí que necesito empujar al jugador 1 píxel en la dirección normal, para que no se atasque en las cosas, funciona bien.

Respuestas:


13

Simplemente proyecte su vector de movimiento en el plano normal y luego reste el resultado de su vector de movimiento.

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

Algo así de todos modos. Aunque en su hermoso diagrama, la entrada parece estar lejos de la pared, así que estoy un poco confundido.


lo siento, se supone que debe estar frente a una pared vertical allí. terrible dibujo
Iain

1
Estoy un poco confundido sobre el producto dot. ¿No es un producto escalar escalar?
Iain

1
Sí, pero lo multiplica por lo normal (un vector) para obtener el vector de su movimiento no deseado. Un vector (x, y, z) multiplicado por el escalar s te da el vector (sx, sy, sz).
Chris Howe

Hecho, cambió las variables para que coincidan con el diagrama. :)
Chris Howe

@Iain Realmente estoy tratando de entender cómo usar esta respuesta, pero parece que no puedo entenderlo. Cuando creo este código exacto obtengo desiredMotionresultados realmente extraños . ¿Alguna vez lograste que esto funcionara?
prueba

1

Si bien es sencillo eliminar el componente del movimiento en la dirección de lo normal, puede adaptarse a su juego para rotar el vector de movimiento. Por ejemplo, en un juego de acción en tercera persona, puede ser fácil quedar un poco colgado en las paredes y otros límites, por lo que puede hacer algunas conjeturas sobre lo que el jugador 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);
   }
}

Agradable. Pero si escalas por un factor de fudge, ¿eso te hace golpear la pared en lugar de deslizarte a lo largo de ella, o es solo un caso de retocarla?
Chris Howe

Mi pensamiento es que lo ajustas para que se vea bien; ciertamente, si es demasiado grande, parecerá que estás rebotando, pero si es lo suficientemente sutil, evitarás que te cuelguen en las curvas leves en la superficie.
dash-tom-bang
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.