J'essaie d'implémenter un système physique client / serveur à l'aide de Bullet, mais j'ai des problèmes pour synchroniser les choses.
J'ai implémenté un état de mouvement personnalisé qui lit et écrit la transformation de mes objets de jeu et cela fonctionne localement, mais j'ai essayé deux approches différentes pour les jeux en réseau:
- Les objets dynamiques sur le client qui se trouvent également sur le serveur (par exemple, les débris aléatoires et autres éléments sans importance) sont rendus cinématiques. Cela fonctionne correctement mais les objets ne se déplacent pas très facilement
- Les objets sont dynamiques sur les deux mais après chaque message du serveur indiquant que l'objet a bougé, j'ai défini la vitesse linéaire et angulaire sur les valeurs du serveur et j'ai appelé btRigidBody :: procéderToTransform avec la transformation sur le serveur. J'appelle également btCollisionObject :: activate (true); pour forcer l'objet à mettre à jour.
Mon intention avec la méthode 2 était essentiellement de faire la méthode 1 mais de détourner Bullet pour faire la prédiction d'un pauvre homme au lieu de faire la mienne pour lisser la méthode 1, mais cela ne semble pas fonctionner (pour des raisons qui ne sont pas claires à 100% pour moi même en passant par Bullet) et les objets se retrouvent parfois à des endroits différents.
Suis-je dans la bonne direction? Bullet semble avoir son propre code d'interpolation intégré. Cela peut-il m'aider à améliorer la méthode 1? Ou mon code de méthode 2 ne fonctionne-t-il pas parce que je le piétine accidentellement?
EDIT: Un autre problème avec la méthode 1 que je viens de remarquer est que la réponse de collision sera très éloignée pour les collisions contre des objets non synchronisés. Les corps cinétiques tirent parfois à l'infini car ils ne peuvent pas être repoussés.
Réponses:
Vous avez besoin d'une bonne prédiction côté client .
Vous devriez vraiment lire en détail le lien que Roy T. vous a fourni dans son commentaire . Il décrit ce qu'il faut faire avec l'entrée du joueur et la physique des personnages, mais le principe reste le même pour la "physique pilotée par le serveur".
Ce n'est pas trivial à implémenter mais en quelques mots, pour les objets de jeu qui doivent être synchronisés:
Alors oui, vous vous dirigez dans la bonne direction avec votre méthode 2. Il ne suffit pas de remplacer les valeurs, vous obtiendrez des sauts sur le client, ce que vous devez faire est d'interpoler en douceur et en continu sur les valeurs du serveur.
Pour votre bug actuel, je ne connais pas Bullet, mais certaines valeurs vous manquent probablement, par exemple, vous avez défini les vitesses linéaires et angulaires, mais avez-vous défini les accélérations?
la source
Ce que je fais personnellement, c'est que celui qui héberge le jeu crée le monde phsyics et synchronise les objets avec les clients. Même si c'est un schéma de réseau p2p, je base toujours le moteur physique sur l'un des clients des joueurs.
Il n'est même pas nécessaire de synchroniser d'autres éléments physiques que j'utilise qui sont uniquement des bonbons pour les yeux.
Dans un prototype que j'ai fabriqué il y a quelque temps, appelé "kettlezerkerker", j'ai exécuté de la physique sur l'hôte et les effets de particules (utilisant également la physique) n'étaient pas synchronisés sur un réseau mais indépendants pour chaque client, car ils étaient agréables pour les yeux.
la source
Il est impossible de mettre en œuvre des mondes de physique synchrone de réseau. Petite différence à l'étape N, bien plus grande différence à l'étape N + 1 Vous ne pouvez pas appliquer de forces ou d'impulsions pour garder la synchronisation et avoir l'air réaliste.
Solutions:-
Vous pouvez envisager de synchroniser seulement quelques objets comme des personnages ou des voitures de course, surtout s'ils sont cinématiques. Mais la plupart des régions du monde ne seraient pas synchronisées pour paraître réalistes.
Vous pouvez avoir un univers physique sur le serveur et diffuser les positions et les vitesses des objets aux clients.
la source