Física de balanceo para el movimiento de jugadores (como se ve en Spider-Man 2 y Energy Hook)

¡Hola! Soy Jamie Fristrom de Laboratorios Happion. Tal vez me recuerdes de juegos como Die By The Sword, Spider-Man 2 y Schizoid ... todos los cuales, de una forma u otra, incluían la cuerda. Últimamente he estado trabajando en un juego llamado Energy Hook, recientemente lanzado en Kickstarter, que trata sobre cuerdas. (Bueno, de todas formas se trata de tu viga de grapa con motor de gravedad).


Voy a discutir cómo me gusta implementar una mecánica de juego de balanceo de cuerda. Cuando comencé a trabajar en Energy Hook, principalmente hice todo con mi propio código personalizado. Creo que es posible simplemente ir a Unity y usar la junta configurable para hacer cosas muy similares, pero en ese momento no estaba disponible. Estoy bastante seguro de que esta ha sido la decisión correcta, de todos modos, porque me da control sobre todo, y puedo compartirlo contigo.


Los fundamentos de hacer el swing de la manera que lo hice - usando restricciones - En realidad son bastante simples. (Espero no estar decepcionado cuando vea lo que está debajo del capó). Funciona de la misma manera, ya sea que esté haciendo un juego 2D o un juego 3D, es solo que los vectores son diferentes, así que comenzaré con 2D y luego Discutir algunas arrugas al ir a tres dimensiones..

Este artículo también asume que estás usando un motor de juego como Unity que puede hacer mucho del trabajo por ti, como el lanzamiento de rayos contra la geometría y la orientación de un personaje, con llamadas a funciones simples. Si está utilizando su propio motor, es posible que tenga que hacer las cuentas usted mismo.



Simulaciones físicas vs movimiento enlatado

Hay dos formas en que las simulaciones de juegos a menudo funcionan. La mayoría de los juegos en tercera persona han enlatado todo; Animaciones enlatadas y movimientos enlatados para que todo se vea perfecto, los pies del personaje no se deslicen, directamente desde el programa de animación del animador hasta nosotros. La alternativa es una simulación mucho más física: estás simulando la física: aceleración, velocidad, gravedad, muchos juegos en primera persona hacen esto, pero los juegos en tercera persona tienden a evitarlo, porque es mucho más fácil tener los pies del personaje. diapositiva y las cosas físicas no coinciden con la animación.

Si quieres hacer un swing de cuerda no enlatado (a diferencia de un swing de cuerda enlatado, como se vio en el primer Pitfall, o los primeros juegos de Spider-Man como Neversoft en la PSX), un swing de cuerda que en realidad es un físico simulación y, por lo tanto, tal vez tenga libertad y matices y la sensación visceral que la gravedad y el impulso reales pueden brindarle, entonces querrá hacerlo de la segunda manera: haga que todo sea una simulación física y evite hacer cosas enlatadas que maten. El impulso del personaje. Entonces, todo fluirá..

Así hago las cosas con Energy Hook..


Hay una tonelada de artículos sobre cómo simular la física; aquí hay uno con una demo en Flash incorporada. Puede hacer la integración de Euler o la integración de Verlet, en realidad no importa. (No te enseñaré sobre Euler vs. Verlet aquí, pero déjame decirte que los conceptos no son tan aterradores como parecen).

Supongamos que hacemos la integración ósea simple de Euler. El paso de tiempo del juego de nuestro personaje podría verse así, donde la aceleración está determinada por la gravedad y cómo estás empujando el stick:

 avatar.velocity = avatar.velocity + avatar.acceleration * deltaT; avatar.position = avatar.position + avatar.velocity * deltaT;

(Nota: esta es en realidad una aproximación aproximada: puede obtener una aproximación mejor, menos dependiente de la velocidad de fotogramas con avatar.position = avatar.position + (avatar.oldvelocity + avatar.velocity) * deltaT / 2.0f, y puedes obtener una simulación casi perfecta con algo como esto, pero tus jugadores probablemente no lo notarán.)

Artículos Relacionados
  • Simule telas desechables y ragdolls con una integración simple de Verlet
  • Cómo crear un motor de física 2D personalizado

Restringirlo

Tu juego probablemente tiene algún sistema para chocar con la geometría mundial. Probablemente se ve algo como esto:

 Vector testPosition = avatar.position + avatar.velocity * deltaT; Intersección vectorial si (RayCast (posición, testPosition, out intersection)) // atravesamos una pared, retiremos el carácter, // usando la normal de la pared // con un espacio de 1 unidad para sala de respiración testPosition = intersección + intersección.normal; 

¿Qué pasa con la velocidad de tu avatar cuando golpean un obstáculo? No tiene sentido para tu avatar mantener la misma velocidad a través de la pared. Algunos juegos pueden hacerte rebotar, usando la normal de donde te cruzaste para reflejar tu velocidad; otros juegos podrían dejarte deslizar por la pared; otros estarán en algún punto intermedio. Veamos el código para deslizarse a lo largo de una pared:

 avatar.velocity = (testPosition - avatar.position) / deltaT; avatar.position = testPosition;

(Si está haciendo la integración de Verlet, donde cada cuadro ya está determinando la velocidad simplemente mirando los datos de posición anteriores, este paso ya está hecho para usted).

Además, como los videojuegos son lo que son piruetas, es probable que a menudo encuentres que la posición de tu personaje se ajusta repentinamente de un cuadro a otro en ciertos casos de esquina. Cuando esto suceda, su velocidad pasará por el techo. Mi solución para eso es simplemente un truco: verifica si su velocidad es demasiado extrema y arréglala si lo hace..

¿Qué hace ese código cuando golpeas una pared en ángulo? El primer cuadro cambia tu velocidad dramáticamente cuando golpeas la pared, pero todavía te empuja a través de la pared. En el siguiente cuadro, tu avatar se actualiza nuevamente en la pared, y luego vuelve a empujarlo, pero ahora la velocidad es la nueva posición del avatar, se desliza a lo largo de la pared, menos su posición anterior, contra la pared, por lo que es paralela a la pared.

Esta es una gran simplificación de lo que sucede en el mundo real cuando un objeto choca con otro, pero la mayoría de tus jugadores no lo notarán ni se preocuparán..

En este punto, sin embargo, hemos limitado con éxito la posición y velocidad de nuestro avatar con las paredes y los pisos de nuestro juego. Así que ahora estamos listos.

Restricción con correas en lugar de paredes

Ahora imagine que su avatar ya está conectado por una cuerda virtual a un punto virtual. En lo que a nosotros respecta, podemos simplemente considerar que es una pared invisible circular o esférica. Podemos probar la colisión si vemos que te has alejado demasiado del centro del círculo y regresa al avatar.

 if (amITethered) if (testPosition - tetherPoint) .Length ()> tetherLength) // hemos pasado el final de nuestra cuerda // volvemos a colocar el avatar. testPosition = (testPosition - tetherPoint) .Normalized () * tetherLength; 

Ahora, el mismo ajuste de velocidad que nos hizo deslizar a lo largo de las paredes también nos hará deslizar a lo largo del interior de este círculo o esfera virtual.


Física de balanceo: caída con una cuerda - Marco 1
Física de balanceo: caer con una cuerda - Marco 2
Física de balanceo: caer con una cuerda - Marco 3

Un poco de sutileza y matiz

En este punto, tienes un juego de swinging. Pero probablemente habrá algunas cosas que se interpongan en el camino de la diversión para tus jugadores, y aquí es donde un poco de piratería puede mejorar las cosas..

Holgura

Dependiendo de su juego, y si se supone que simula una cuerda o una red elástica o una viga de garra, puede tener diferentes enfoques de holgura y elasticidad. Puedes simular muchas cosas ajustando el tetherLength. Si desea aflojar su red elástica o viga de garra, puede acortar el tetherLength a medida que el jugador se acerca al punto de amarre:

 tetherLength = (avatar.position - tetherPoint) .Length ();

Pero si es una cuerda no elástica, dejarías la tetherLength sin tocar.

Para la elasticidad, puedes tener un longitud deseada eso es fijo y un currentLength que continuamente trata de acercarse al longitud deseada - Esto también será útil para nuestro próximo paso:

Pero no quiero golpear el suelo!

¿Qué pasa si tu avatar comienza en un lugar bajo y trata de balancearse? Es bastante obvio que no llegarán muy lejos. Una solución rápida para esto es verificar a qué altura del punto desde donde se mueve el columpio y acortar la longitud de su cuerda para que despeje el suelo.

Sin embargo, no puede acortarlo en un solo fotograma, ya que de repente se dispararán al aire, así que aquí, teniendo un longitud deseada eso es lo suficientemente corto como para no tocar el suelo y una currentLength que se acerca rápidamente longitud deseada te conseguirá la autorización que quieras.

El Avatar's Up

Si tu avatar es una figura humanitaria, no tiene mucho sentido que aparezcan perfectamente verticales mientras se balancean. Orientándolos para que se vean como si estuvieran colgando de la cuerda, así que están al revés si están haciendo un bucle, por ejemplo, podría verse así en Unity:

 Vector myUp = (avatar.position - tetherPoint); avatar.rotation = Quaternion.LookRotation (avatar.rotation.forward, myUp);

Esto permitirá que el avatar se mueva hacia atrás. También puedes usar la velocidad del avatar para su avance (eso es lo que hago), o dejar que giren locamente ...

Envolviendo las cosas

En el mundo real, las cuerdas envuelven cosas. Una forma rápida de simular eso en su código es emitir a lo largo de la cuerda virtual cada fotograma y, si llega a algo, cree un nuevo punto de conexión donde se interseca. Esto no se verá bien si el avatar se balancea hacia atrás sobre una cuerda no pegajosa, pero está bien para una telaraña pegada, una lengüeta o una viga de agarre.

Ajustar la forma en que se envuelven las cuerdas puede tener un gran impacto en la diversión. De repente, envolver alrededor de un afloramiento puede tomar al jugador por sorpresa y frustrarlo. Tuvimos una solución de tres pasos en Spider-Man 2: si estuvieras demasiado cerca del afloramiento, la web se rompería; si estuvieras en una distancia media, la web se envolvería; Y si estuvieras lejos, la web simplemente pasaría por.


Consideraciones para 3D

Lo más difícil de llevar este mecánico 2D a 3D es tener en cuenta la interfaz para el jugador: cómo eligen los puntos del mundo para cambiar. Diferentes juegos utilizan diferentes métodos para elegir tal punto. Ratchet & Clank tiene puntos fijos en el mundo que puedes resolver; con el modo Quake-grappling-hook mod y Bionic Commando: Rearmed apunta la cámara a lo que desea adjuntar; Spider-Man 2 y Energy Hook emiten rayos en relación con el personaje, y donde los rayos se intersecan con la geometría física, es el punto donde se une..


Casi todos estos métodos implican la emisión de rayos contra la geometría física del mundo, ya sea a lo largo de la línea de la cámara o desde el personaje hasta el punto del clic del mouse: la intersección de la transmisión de rayos determina su nuevo punto de anclaje.

Por ejemplo, aquí hay un raycast con aspecto de ratón que podría ser bueno para un juego en primera persona:

 RaycastHit wallData; if (Physics.Raycast (camera.position, camera.forward, out WallData, maximumTetherLength)) amITethered = true; tetherPoint = wallData.point; tetherLength = Vector3.Distance (wallData.point, avatar.position); 

Bumping Into Stuff

Chocar contra paredes y cosas similares también tiende a suceder mucho más a menudo en un juego en 3D que en un juego en 2D, especialmente cuando se está atando a las paredes. Hay una variedad de cosas que puedes hacer para que esto sea menos molesto..

  • Deje que el jugador gire en el aire: la física no tiene mucho que decir al respecto, pero de alguna manera se siente bien. Esa es una de las cosas que hicimos en Spider-Man 2, y por qué obtienes un jetpack en Energy Hook.
  • Reproduce una animación genial: haz que el avatar haga algún tipo de giro o giro cuando golpee una pared, y luego se siente menos como un error y más como "¡Yo quería hacer eso!"
  • Mantenlos fuera de la pared: Ultimate Spider-Man hizo esto: si te acercas demasiado a una pared, te alejará de ella suavemente. Parecía un poco extraño si soltabas el palo y simplemente dejabas que tu avatar se quedara allí (se alejaban flotando de la pared en un ángulo extraño), pero para el resto del juego fue una mejora. (¿Podrías tener lo mejor de ambos mundos al alejarte solo si el personaje va a cierta velocidad?)
  • Recompénsalos por no golpear la pared en primer lugar: esta es la estrategia del Gancho de Energía: enséñale al jugador a evitar golpear las paredes, recompensándolos por tener columpios limpios. Por un lado, les anima a balancearse bastante; Por otro lado, cuando golpean la pared es mucho más frustrante, porque pierden sus puntos de estilo..


Entonces, Qué esperas?

¡Salga y haga sus propios juegos de swing, y hágame saber lo que se le ocurre! Nunca puedo tener suficiente de juegos de swing.

Espero que hayas encontrado útil este artículo. Si es así, por favor apoye el Arrancador de Energía Energy Hook o vote por Steam Greenlight. Gracias!