Estoy tratando de implementar un sistema físico de cliente / servidor usando Bullet, sin embargo, tengo problemas para sincronizar las cosas.
He implementado un estado de movimiento personalizado que lee y escribe la transformación de los objetos de mi juego y funciona localmente, pero he probado dos enfoques diferentes para juegos en red:
- Los objetos dinámicos en el cliente que también están en el servidor (p. Ej., Desechos no aleatorios y otras cosas sin importancia) se hacen cinemáticos. Esto funciona correctamente pero los objetos no se mueven muy suavemente
- Los objetos son dinámicos en ambos, pero después de cada mensaje del servidor de que el objeto se ha movido, configuro la velocidad lineal y angular a los valores del servidor y llamo a btRigidBody :: proceToTransform con la transformación en el servidor. También llamo btCollisionObject :: activar (verdadero); para forzar al objeto a actualizar.
Mi intención con el método 2 era básicamente hacer el método 1, pero secuestrar a Bullet para hacer la predicción de un hombre pobre en lugar de hacer la mía para suavizar el método 1, pero esto no parece funcionar (por razones que no son 100% claras para incluso cuando paso por Bullet) y los objetos a veces terminan en diferentes lugares.
¿Me dirijo en la dirección correcta? Bullet parece tener su propio código de interpolación incorporado. ¿Puede eso ayudarme a hacer que el método 1 funcione mejor? ¿O mi código del método 2 no funciona porque accidentalmente estoy pisoteando eso?
EDITAR: Otro problema con el método 1 que acabo de notar es que la respuesta de colisión estará lejos para colisiones contra objetos no sincronizados. Los cuerpos cinéticos disparan cosas hasta el infinito a veces, ya que no pueden ser rechazados.
Respuestas:
Necesita una predicción adecuada del lado del cliente .
Realmente deberías leer en detalle el enlace que Roy T. te proporcionó en su comentario . Describe qué hacer con la entrada del jugador y la física del personaje, pero el principio sigue siendo el mismo para la "física dirigida por el servidor".
Esto no es trivial de implementar, pero en pocas palabras, para los objetos del juego que necesitan estar sincronizados:
Entonces, sí, se dirige en la dirección correcta con su método 2. Sin embargo, anular los valores no es suficiente, obtendrá saltos en el cliente, lo que debe hacer es interpolar sin problemas y continuamente los valores del servidor.
Para su error real, no estoy familiarizado con Bullet, pero probablemente le faltan algunos valores, por ejemplo, ha establecido las velocidades lineal y angular, pero ¿ha establecido las aceleraciones?
fuente
Lo que hago personalmente es quien aloja el juego crea el mundo de la física y sincroniza los objetos con los clientes. Incluso si es un esquema de red p2p, sigo basando el motor de física en uno de los clientes de los jugadores.
Otra física que uso que es puramente dulce ni siquiera necesita sincronizarse.
En un prototipo que hice hace un tiempo llamado "boilerzerker", ejecuté la física en el host y los efectos de partículas (también usando física) no se sincronizaron a través de una red, sino que eran independientes para cada cliente porque eran muy atractivos.
fuente
Es imposible implementar mundos de física síncrona de red. Pequeña diferencia en el paso N, por supuesto, una diferencia mucho más grande en el paso N + 1. No puede aplicar fuerzas o impulsos para mantener la sincronización y parecer realista.
Soluciones: -
Puede considerar sincronizar solo unos pocos objetos, como personajes o autos de carreras, especialmente si son cinemáticos. Pero la mayor parte del mundo no estaría sincronizada para parecer realista.
Puede tener mundos físicos en el servidor y transmitir posiciones y velocidades de objetos a los clientes.
fuente