Como posso manter dois jogadores de corrida sincronizados?

8

Estou trabalhando em um jogo para celular Unity, muito parecido com uma versão multiplayer de Temple Run . Estou vendo uma latência de rede flutuante (geralmente de 200 a 500 ms) por causa da plataforma móvel.

Os personagens dos dois jogadores são mostrados como correndo pelo mesmo caminho e devem executar ações simples (pular, deslizar, ligar, etc.) para ultrapassar obstáculos.

Quando uma mensagem chega atrasada, o jogo assume que o jogador remoto passou por um obstáculo. Isso geralmente funciona bem, mas no caso de um jogador ser morto por um obstáculo, quero que o jogador remoto pareça morrer no mesmo obstáculo / posição que o jogador local. Devido à latência, o jogador remoto parece ter cruzado o obstáculo antes mesmo da mensagem anunciando sua morte.

Como posso manter os players sincronizados?


Tentei mover o player remoto de volta para a posição de morte dos jogadores locais imediatamente quando a mensagem de morte chega, parece estranha visualmente e pode causar outros problemas de sincronização.

Zohaib Javed
fonte

Respostas:

10

Analise de problemas

A comunicação em tempo real através de uma conexão de alta latência é obviamente impossível.

É claro que você pode tentar uma ilusão (como está fazendo, fazendo o player remoto parecer ter passado por um obstáculo quando ainda não é conhecido). Quando essa ilusão falha (como a sua quando o jogador remoto não passou do obstáculo, mas morreu ), nada mais pode ser feito.

o problema

Em um caso (como aqui) em que a falha da ilusão parece realmente ruim , pode ser mais fácil aceitar os fatos e fazer o possível para representar a situação como ela realmente é.

Solução potencial

Que tal literalmente desacelerar o outro jogador se a decisão deles está demorando para se propagar?

uma solução

Cada jogador vê uma imagem do outro, mas essa imagem diminui ao se aproximar dos obstáculos para os quais a mensagem de decisão ainda está no ar. Somente quando a mensagem é recebida, elas parecem passar ou falhar no obstáculo. Após o obstáculo, a imagem acelera novamente para recuperar o atraso, desacelerando novamente para a próxima, se necessário.

Em uma conexão de baixa latência, a decisão chega em breve e a desaceleração e a aceleração serão insignificantes. Em uma conexão de alta latência, isso fará o outro jogador ficar para trás, mas garante que o estado do jogo mais importante de "quem passou por esse obstáculo" seja consistente para os dois jogadores.

Anko
fonte
Obrigado pela sua resposta. Já tentamos a solução em potencial que você propôs, mas não a considerou viável devido aos seguintes motivos: 1.O primeiro motivo é a alta velocidade do meu jogo. Para cobrir uma janela de 200ms, eu teria que diminuir a velocidade do player remoto para 1/4 da velocidade, o que causa uma anomalia visual muito desagradável e visível, especialmente no caso em que o jogador está correndo lado a lado. 2.Como a latência está flutuando, é realmente difícil calcular a redução de velocidade para o player remoto, o que garantiria que a mensagem chegasse antes de atravessar o obstáculo.
Zohaib Javed
2
@ZahaibJaved Muitas vezes, a única solução real é ocultar a latência através de animações. Em vez de diminuir a velocidade à medida que se aproximam do obstáculo, considere parar completamente no limite e executar uma animação "preparando-se para pular" que leva um segundo inteiro para ser reproduzida. Depois que o pacote "eles conseguiram" aparecer, execute o salto e o lerp reais para a posição real.
BlueRaja - Danny Pflughoeft
Desculpe pela resposta atrasada. Portanto, a solução que eu implementei foi a cena inicial, onde todos os jogadores podem ser vistos. O jogador local está sempre na primeira posição. Após a conclusão da cena. Apenas movo todo o player remoto para trás o suficiente para que eles tenham algum tempo para receber as informações de que o player local morreu em um obstáculo específico ou deslize ou pule corretamente no caminho. E no final, há um caminho reto, onde eu apenas sincronizo os jogadores novamente. Portanto, esse resultado é exibido corretamente.
Zohaib Javed
4

Para complementar a resposta de Anko, você pode mudar um pouco o design do jogo, adicionando a conseqüência do obstáculo que falhou após a falha, por exemplo, um salto falhado resulta em aterrissar em uma poça de lama que desqualifica o jogador. Dessa forma, o outro jogador percebe a falha vendo o outro cair na lama, enquanto o jogador que falha a vê imediatamente.

Aqui está um bom post sobre esse problema (não é tão recente, mas é bastante interessante): Gerenciamento de tempo e sincronização de Darrin West .

Vaillancourt
fonte
1

É importante que o jogador local saiba a posição exata da morte do jogador remoto? Digamos que o jogador remoto não possa pular um dos seus obstáculos e, portanto, morreu.

O jogador morto veria sua morte imediatamente e continuaria a partir do local do acidente. Nada de mágico aqui.

O jogador local (o que ainda está vivo e chutando) veria o jogador remoto passar pelo obstáculo com sucesso. Uma notificação de morte chegaria. O jogador remoto tropeçava, caía e desaparecia lentamente. Na próxima vez que você souber a posição do jogador remoto, ele desaparecerá nessa posição exata, funcionando normalmente novamente. Em tal configuração, os jogadores estariam cientes da latência, mas a latência seria representada como um elemento do jogo (tropeçando para baixo), em vez de jogadores aparecerem e desaparecerem.

Se a velocidade dos dois jogadores for constante, a trajetória de corrida for predefinida e o tempo necessário para se recuperar de uma queda for conhecido, você poderá eliminar completamente a parte que está desaparecendo / desaparecendo. Imagine um jogador remoto morrendo em um dos obstáculos. Sua representação local ainda está em execução quando uma notificação é recebida. O player é exibido tropeçando imediatamente. Leva tempo para eles se levantarem e começarem a correr novamente. Na verdade, leva tanto tempo quanto se eles fossem mostrados morrendo no obstáculo. Assim, quando eles estão novamente em funcionamento, as posições local e remota são sincronizadas.


fonte