Discordo um pouco da resposta de Philipp ; ou pelo menos com a forma como ele a apresentou. Dá a impressão de que mudar o mundo ao redor do player pode ser uma idéia melhor; quando é exatamente o oposto. Então aqui está a minha própria resposta ...
Ambas as opções podem funcionar, mas geralmente é uma má idéia "inverter a física" movendo o mundo ao redor do jogador, e não o jogador ao redor do mundo.
Perda / desperdício de desempenho:
O mundo normalmente terá muitos objetos; muitos, se não a maioria, estáticos ou adormecidos. O jogador terá um ou relativamente poucos objetos. Mover o mundo inteiro ao redor do jogador significa mover tudo na cena, exceto o jogador. Objetos estáticos, objetos dinâmicos adormecidos, objetos dinâmicos ativos, fontes de luz, fontes sonoras, etc; tudo tem que ser movido.
Isso é (obviamente) consideravelmente mais caro do que mover apenas o que realmente está em movimento (o jogador e talvez mais algumas coisas).
Manutenção e extensibilidade:
Mover o mundo ao redor do jogador faz com que o mundo (e tudo nele) seja o ponto em que as coisas estão acontecendo mais ativamente. Qualquer bug ou alteração no sistema significa que, potencialmente, tudo muda. Esta não é uma boa maneira de fazer as coisas; você deseja que os bugs / alterações sejam o mais isolados possível, para que você não tenha comportamentos inesperados em algum lugar em que não tenha feito alterações.
Há também muitos outros problemas com essa abordagem. Por exemplo, ele quebra muitas suposições de como as coisas devem funcionar no mecanismo. Você não seria capaz de usar dinâmico RigidBody
para nada além do player, por exemplo; como um objeto com um anexo RigidBody
não definido como cinemático se comportará inesperadamente ao definir a posição / rotação / escala (o que você faria em todos os quadros, para cada objeto na cena, exceto o jogador 😨)
Portanto, a resposta é apenas mover o jogador!
Bem ... sim e não . Como mencionado na resposta de Philipp, em um tipo de jogo de corredor infinito (ou qualquer jogo com uma grande área explorável contínua), ir muito longe da origem acabaria por introduzir FPPEs ( Erros de precisão de ponto flutuante) visíveis e, ainda mais, eventualmente, transbordar o tipo numérico, causando o travamento do jogo ou, basicamente, fazer com que o mundo do jogo fume de crack ... Em esteróides! Because (porque a essa altura, os FPPEs já tornariam o jogo no crack "normal")
A solução real :
Não faça nem faça os dois! Você deve manter o mundo estático e mover o jogador ao seu redor. Mas "re-enraíza" tanto o jogador quanto o mundo, quando o jogador começa a ficar muito longe da raiz (posição [0, 0, 0]
) da cena.
Se você mantiver a posição relativa das coisas (do jogador para o mundo ao seu redor) e fizer esse processo em uma única atualização de quadro, o jogador (real) nem perceberá!
Para fazer isso, você tem duas opções principais:
- Mova o jogador para a raiz da cena e mova o pedaço do mundo para sua nova posição em relação ao jogador.
- Pense no mundo como uma grade; mova a parte da grade em que o jogador está para a raiz e mova o jogador para sua nova posição em relação à parte da grade.
Aqui está um exemplo deste processo em ação
Mas, quão longe é longe demais?
Se você observar o código-fonte do Unity, eles usarão 1e-5
( 0.00001
) como base para considerar dois valores de ponto flutuante "iguais", dentro Vector2
e Vector3
(os tipos de dados responsáveis pelas posições dos objetos, [euler-] rotações e escalas). Como a perda de precisão de ponto flutuante ocorre em ambos os sentidos do zero, é seguro assumir que qualquer coisa sob 1e+5
( 100000
) unidades de distância da cena raiz / origem é segura para trabalhar.
Mas! Desde a...
- É mais apropriado criar um sistema para lidar com esses processos de reinicialização automática.
- Seja qual for o seu jogo, não há necessidade de uma "seção" contígua do mundo ter 100.000 unidades (metros [?]) De largura.
... então provavelmente é uma boa ideia re-enraizar muito mais cedo / com mais frequência do que a marca de 100.000 unidades. O exemplo de vídeo que forneci parece ser feito a cada 1000 unidades, por exemplo.