Comment synchroniser deux joueurs de course?

8

Je travaille sur un jeu mobile Unity, un peu comme une version multijoueur de Temple Run . Je constate une latence de réseau fluctuante (généralement de 200 à 500 ms) en raison de la plate-forme mobile.

Les deux personnages joueurs sont représentés comme courant sur le même chemin et doivent effectuer des actions simples (saut, glissement, mise sous tension, etc.) pour franchir les obstacles.

Lorsqu'un message arrive en retard, le jeu suppose que le joueur distant a passé un obstacle. Cela fonctionne généralement bien, mais si un joueur est tué par un obstacle, je veux que le joueur distant semble mourir sur le même obstacle / position que le joueur local. En raison de la latence, le joueur distant semble avoir franchi l'obstacle avant même l'arrivée du message annonçant sa mort.

Comment puis-je garder les joueurs synchronisés?


J'ai essayé de déplacer le lecteur distant vers la position de mort des joueurs locaux immédiatement lorsque le message de mort arrive, il semble visuellement gênant et pourrait poser d'autres problèmes de synchronisation.

Zohaib Javed
la source

Réponses:

10

Analyse du problème

La communication en temps réel sur une connexion à latence élevée est évidemment impossible.

Vous pouvez bien sûr tenter une illusion (comme vous le faites en faisant croire que le lecteur distant a passé un obstacle alors qu'il n'est pas encore connu). Lorsque cette illusion échoue (comme la vôtre lorsque le joueur distant n'a pas franchi l'obstacle, mais est mort à la place), rien ne peut plus être fait.

le problème

Dans un cas (comme ici) où l'échec de l'illusion semble vraiment mauvais , il pourrait être plus facile d'accepter les faits et de faire de votre mieux pour représenter la situation telle qu'elle est réellement.

Solution potentielle

Que diriez-vous de ralentir littéralement l'autre joueur si sa décision prend du temps à se propager?

une solution

Chaque joueur voit une image de l'autre, mais cette image ralentit à l'approche d'obstacles pour lesquels le message de décision est toujours dans l'air. Ce n'est qu'une fois le message reçu qu'ils semblent passer ou échouer l'obstacle. Après l'obstacle, l'image accélère à nouveau pour rattraper son retard, ralentissant à nouveau pour le suivant, si nécessaire.

Sur une connexion à faible latence, la décision arrive bientôt et le ralentissement et l'accélération seront négligeables. Sur une connexion à latence élevée, cela donnera l' impression que l'autre joueur est à la traîne, mais garantit que l' état de jeu le plus important de "qui a franchi cet obstacle" est cohérent pour les deux joueurs.

Anko
la source
Merci pour votre réponse. Nous avons déjà essayé la solution potentielle que vous avez proposée mais nous ne l'avons pas trouvée possible pour les raisons suivantes: 1. La première raison est la vitesse élevée de mon jeu. Afin de couvrir une fenêtre de 200 ms, je devrais ralentir le lecteur distant à 1 / 4ème vitesse, ce qui provoque une anomalie visuelle très désagréable et visible spécialement dans le cas où le joueur courait côte à côte. 2.La latence étant fluctuante, il est vraiment difficile de calculer la réduction de vitesse pour le lecteur distant, ce qui garantirait que le message arrivera avant qu'il ne franchisse l'obstacle.
Zohaib Javed
2
@ZahaibJaved Souvent, la seule vraie solution est de masquer la latence à travers des animations. Plutôt que de ralentir lorsqu'ils arrivent à l'obstacle, envisagez de vous arrêter complètement au bord et de réaliser une animation "se préparer à sauter" qui prend une seconde complète à jouer. Une fois que le paquet "l'ont-ils fait" arrive-t-il, effectuez le saut réel et lerp vers l'avant à leur position réelle.
BlueRaja - Danny Pflughoeft
Désolé pour la réponse tardive. Donc, la solution que j'ai implémentée était dans la cinématique de départ est jouée où tous les joueurs peuvent être vus. Le joueur local est toujours en première position. Une fois la cinématique terminée. Je déplace juste le tout le joueur distant suffisamment derrière pour qu'il puisse avoir le temps de recevoir l'information que le joueur local est mort sur un obstacle spécifique ou glisser ou sauter correctement sur le chemin. Et à la fin, il y a un chemin droit où je synchronise à nouveau les joueurs. Donc, ce résultat s'affiche correctement.
Zohaib Javed,
4

Pour compléter la réponse d'Anko, vous pouvez changer un peu la conception de votre jeu en ajoutant la conséquence de l'obstacle échoué après l'échec, par exemple, un saut échoué entraîne l'atterrissage dans une flaque de boue qui disqualifie le joueur. De cette façon, l'autre joueur remarque l'échec en voyant l'autre tomber dans la boue, tandis que le joueur qui échoue le voit tout de suite.

Voici un joli billet de blog sur ce problème (ce n'est pas si récent mais c'est assez intéressant): Gestion du temps et synchronisation de Darrin West .

Vaillancourt
la source
1

Est-il si important pour le joueur local de connaître la position exacte de la mort du joueur distant? Disons que le joueur distant ne pouvait pas sauter par-dessus l'un de vos obstacles, et est donc mort.

Le joueur mort verrait sa mort immédiatement et continuerait depuis le lieu de l'accident. Rien de magique ici.

Le joueur local (celui qui est toujours vivant et qui donne des coups de pied) verrait le joueur distant passer l'obstacle avec succès. Une notification de décès entrait. Le joueur distant trébuchait sur ses pieds, tombait et disparaissait lentement. La prochaine fois que vous connaîtrez la position du joueur distant, le joueur se fondra dans cette position exacte et fonctionnera à nouveau normalement. Dans une telle configuration, les joueurs seraient conscients de la latence, mais la latence serait représentée comme un élément de jeu (trébuchant) plutôt que d'apparaître et de disparaître de façon saccadée.

Si la vitesse des deux joueurs est constante, la trajectoire de course est prédéfinie et le temps nécessaire pour se remettre d'une chute est connu, vous pouvez éliminer complètement la partie qui s'estompe / disparaît. Imaginez un joueur distant mourant à l'un des obstacles. Sa représentation locale est toujours active lorsqu'une notification arrive. Le joueur trébuche immédiatement. Il leur faut du temps pour se lever et recommencer à courir. En fait, cela prend autant de temps que si on les montrait en train de mourir à l'obstacle. Ainsi, lorsqu'ils sont à nouveau opérationnels, les positions locales et distantes sont synchronisées.


la source