Veja também esta resposta .
Existem duas maneiras comuns de usar Lerp:
1. Mistura linear entre um começo e um fim
progress = Mathf.Clamp01(progress + speedPerTick);
current = Mathf.Lerp(start, end, progress);
Esta é a versão com a qual você provavelmente está mais familiarizado.
2. Facilidade exponencial em direção a um alvo
current = Mathf.Lerp(current, target, sharpnessPerTick);
Observe que nesta versão o currentvalor aparece como saída e como entrada. Ele desloca a startvariável, por isso estamos sempre começando de onde quer que nos mudemos na última atualização. É isso que fornece essa versão da Lerpmemória de um quadro para o outro. A partir deste ponto inicial em movimento, movemos então uma fração da distância em direção à targetditada por um sharpnessparâmetro.
Esse parâmetro não é mais uma "velocidade", porque nos aproximamos do alvo de maneira semelhante ao zeno . Se sharpnessPerTickfosse 0.5, na primeira atualização nos moveríamos a meio caminho do nosso objetivo. Na próxima atualização, moveríamos metade da distância restante (portanto, um quarto da nossa distância inicial). Então, no próximo, nos moveríamos pela metade novamente ...
Isso proporciona uma "facilidade exponencial", onde o movimento é rápido quando está longe do alvo e diminui gradualmente à medida que se aproxima assintoticamente (embora com números de precisão infinita nunca o alcance em um número finito de atualizações - para nossos propósitos, fica perto o suficiente). É ótimo para perseguir um valor-alvo móvel ou suavizar uma entrada barulhenta usando uma " média móvel exponencial ", geralmente usando um sharpnessPerTickparâmetro muito pequeno como 0.1ou menor.
Mas você está certo, há um erro na resposta votada que você vincula. Não está corrigindo deltaTimeo caminho certo. Este é um erro muito comum ao usar esse estilo de Lerp.
O primeiro estilo de Lerpé linear, para que possamos ajustar linearmente a velocidade multiplicando por deltaTime:
progress = Mathf.Clamp01(progress + speedPerSecond * Time.deltaTime);
// or progress = Mathf.Clamp01(progress + Time.deltaTime / durationSeconds);
current = Mathf.Lerp(start, end, progress);
Mas nossa flexibilização exponencial é não linear , portanto, apenas a multiplicação de nosso sharpnessparâmetro por deltaTimenão dará a correção correta do tempo. Isso aparecerá como uma trepidação no movimento, se a taxa de quadros flutuar, ou uma alteração na nitidez da flexibilização, se você passar de 30 para 60 de forma consistente.
Em vez disso, precisamos aplicar uma correção exponencial para nossa facilidade exponencial:
blend = 1f - Mathf.Pow(1f - sharpness, Time.deltaTime * referenceFramerate);
current = Mathf.Lerp(current, target, blend);
Aqui referenceFramerateestá apenas uma constante 30para manter as unidades sharpnessda mesma forma que estávamos usando antes de corrigir o tempo.
Há um outro erro discutível nesse código, que está usando Slerp- a interpolação linear esférica é útil quando queremos uma taxa de rotação exatamente consistente por todo o movimento. Mas se usarmos uma facilidade exponencial não linear de qualquer maneira, Lerpforneceremos um resultado quase indistinguível e é mais barato. ;) Os quaternions lerp são muito melhores que as matrizes, por isso geralmente é uma substituição segura.