Como é dito aqui :
Time.time
A hora no início desse quadro (somente leitura). Este é o tempo em segundos desde o início do jogo.
E como eu sei, o tempo é armazenado em flutuação. Então, minha pergunta é o que acontecerá quando o valor do tempo se tornar muito grande? Pode transbordar? Vai perder precisão e causar bugs? O jogo vai travar ou o quê?
Respostas:
Existe um risco real de perda de precisão ao usar um flutuador de precisão única .
Ele ainda manterá a precisão no segundo mais próximo por 97 dias . Mas em jogos, geralmente nos preocupamos com a precisão na ordem da duração de um quadro.
Um valor de tempo de flutuação de precisão única em segundos começa a perder a precisão de milissegundos após cerca de 9 horas .
Isso já não está fora do campo de possibilidade de uma única sessão de jogo ou de deixar o jogo rodando "AFK" enquanto você estiver no trabalho / na escola ou dormindo. (Esse é um dos motivos pelos quais uma maneira comum de testar um jogo é executá-lo durante a noite e verificar se ele ainda é reproduzido corretamente pela manhã)
Nos consoles modernos, onde os jogos geralmente são suspensos e retomados entre as sessões de jogo, em vez de serem encerrados por completo, não é inesperado que uma "sessão única" do ponto de vista do jogo exceda 9 horas de tempo de execução, mesmo quando jogadas em rajadas curtas.
Assumindo que o Unity
deltaTime
é calculado a partir de uma fonte de tempo de maior precisão, confirmada pelos experimentos de Peter em outra resposta, contar comdeltaTime
tempos de escala de quadros é relativamente seguro (apenas tome cuidado para acumular durações muito longas somandodeltaTime
valores - adicionando pequenos incrementos a um flutuador maior é uma receita clássica para perda de precisão, mesmo quando você compensa com algoritmos mais experientes ).Como
fixedDeltaTime
mantém o mesmo valor definido, em vez de mudar dinamicamente de quadro para quadro, você também pode colocar um comportamento sensível ao tempo no FixedUpdate para obter garantias mais consistentes de consistência.deltaTime
retornará automaticamente o delta fixo apropriado nesses métodos. Embora possa haver uma frequência de batida entre as atualizações fixas e de quadros, você pode suavizar isso através da interpolação .O que você deseja evitar é calcular as durações subtraindo um registro de data e hora de outro . Após horas de jogo, isso pode causar um cancelamento catastrófico, levando a muito menos precisão do que você obtém no início da corrida. Se a comparação de carimbos de data / hora for importante para seus sistemas, você poderá gerar seu próprio valor de tempo de maior resolução usando outros métodos, como em
System.Diagnostics.Stopwatch
vez deTime.time
.fonte
O valor máximo de flutuação é 3,40282347 * 10 ^ 38, que é igual a 10 ^ 31 anos quando medido em segundos (ou 10 ^ 28 anos quando medido em milissegundos). Confie em mim, não vai transbordar.
A única coisa que pode aparecer é imprecisão. Mas um único número de ponto flutuante de precisão tem uma precisão de 7-8 dígitos decimais. Se usá-lo para medir segundos, é preciso por cerca de 194 dias. Se medir milissegundos, é preciso apenas 4,5 horas. Portanto, depende completamente da precisão de que você precisa e talvez seja necessário encontrar maneiras alternativas, se precisar de precisão de milissegundos (o que você provavelmente não precisa).
fonte
Quanta precisão o seu jogo precisa?
Um flutuador de 32 bits possui 24 bits de precisão. Em outras palavras, no tempo t, a precisão é de ± 2 -23 × t. (Isso não está exatamente correto, mas está próximo e os detalhes exatos não são muito interessantes.)
Se você precisar de 1ms de precisão, depois de 1ms ÷ 2 -23 = 8400 s = 2h 20m, um flutuador de 32 bits não será mais aceitável. Uma precisão de 1ms não é necessária para a maioria dos jogos, mas é considerada necessária para aplicações musicais.
Se o seu jogo rodar em um monitor de 144 Hz e você desejar gráficos com quadros precisos, depois de 1 ÷ 144 Hz ÷ 2 -23 = 58000 s = 16h, um flutuador de 32 bits não será mais aceitável. 16h é muito tempo para rodar um jogo, mas não é inconcebível. Aposto que uma porcentagem significativa de nós já rodou um jogo por 16 horas em um único trecho - mesmo que apenas porque deixamos o jogo rodando e dormimos um pouco. Nesse ponto, as animações e atualizações de física seriam reduzidas para menos de 144Hz.
Se o Unity
Time.deltaTime
for calculado a partir de um relógio de maior precisão, você poderá usá-lo e ainda obter precisão total. Não sei se isso é verdade ou não.Nota
Jogos e outros programas no Windows costumam ser usados
GetTickCount()
para descobrir a hora. Como ele usa um número inteiro de 32 bits para contar milissegundos, ele ocorre a cada 50 dias, se você deixar o computador por tanto tempo. Eu suspeito que muitos jogos travariam, travariam ou se comportariam mal de maneiras bizarras se você os estivesse jogando na marca de 50 dias.Inteiros, como o Windows
GetTickCount()
, correm o risco de transbordar, enquanto os flutuadores, como o UnityTime.time
, correm o risco de perder precisão.fonte
As outras respostas apenas especulam, então escrevi um projeto simples do Unity e o deixei rodar por um tempo. Depois de algumas horas, este é o resultado:
UnityEngine.Time.time
perde a precisão rapidamente. Como esperado, depois de executar o jogo por 4 horas, os valores saltam 1 milissegundo e a imprecisão aumenta depois disso.UnityEngine.Time.deltaTime
mantém sua precisão inicial de menos de milissegundos, mesmo depois que o Unity estiver em execução por horas. Portanto, é praticamente garantido quedeltaTime
é derivado de um contador de alta resolução dependente da plataforma (que geralmente transborda após 10-1000 anos). Ainda existe um pequeno risco quedeltaTime
ainda perderá precisão em algumas plataformas.A imprecisão do tempo é um problema para tudo o que depende
UnityEngine.Time.time
. Um exemplo específico é a rotação (por exemplo, de um moinho de vento), que geralmente é baseadaUnityEngine.Mathf.Sin(UnityEngine.Time.time*rotationSpeed)
. Ainda mais um problema_Time
é explicitamente usado para animações por shaders. Quão alta a imprecisão precisa ser antes de começar a ser perceptível? A precisão de 20 a 30 ms (2 dias) deve ser o ponto em que as pessoas que estão cientes do problema e prestam muita atenção notarão. Entre 50 e 100 ms (5 a 10 dias), pessoas sensíveis que não conhecem o problema começarão a descobrir o problema. De 200 a 300 ms (20 a 30 dias), o problema será óbvio.Até agora eu não testei a precisão de
_SinTime
,_CosTime
eUnity_DeltaTime
, por isso não posso comentar sobre isso.Este é o script que eu usei para testar. Ele está anexado a um
UI.Text
elemento, as Configurações do Player do projeto permitem que o projeto seja executado em segundo plano, e o VSync nas Configurações de Qualidade é definido como Cada Segundo V em Branco:Se você está se perguntando sobre o
0.033203
valor, tenho certeza de que, na verdade0.033203125
, possui uma representação binária de ponto flutuante00111101000010000000000000000000
. Observe os muitos0
s na mantissa.Soluções alternativas
A maioria dos gêneros não precisa de uma solução alternativa. A maioria dos jogadores nem sequer joga um jogo por 100 horas no total, portanto, investir dinheiro para corrigir um problema que as pessoas só notam após alguns dias hipotéticos de tempo de jogo contínuo não é economicamente viável. Infelizmente, não posso apresentar uma solução alternativa simples e universal que conserte a totalidade do problema sem trazer algumas desvantagens significativas.
fonte