이 답변도 참조하십시오 .
사용하는 두 가지 일반적인 방법이 있습니다 Lerp
.
1. 시작과 끝 사이의 선형 혼합
progress = Mathf.Clamp01(progress + speedPerTick);
current = Mathf.Lerp(start, end, progress);
가장 친숙한 버전입니다.
2. 목표를 향한 기하 급수적 완화
current = Mathf.Lerp(current, target, sharpnessPerTick);
이 버전에서는 current
값이 출력 과 입력 모두로 나타납니다 . start
변수를 대체 하므로 마지막 업데이트에서 이동 한 곳에서 항상 시작합니다. 이것이 Lerp
한 프레임에서 다음 프레임 으로이 버전의 메모리를 제공하는 것입니다. 그런 다음이 이동 시작점 target
에서 sharpness
매개 변수 에 의해 지시 된 방향으로 거리의 일부를 이동합니다 .
Zeno와 같은 방식으로 대상에 접근하기 때문에이 매개 변수는 더 이상 "속도"가 아닙니다 . 경우 sharpnessPerTick
했다 0.5
후 첫 번째 업데이트에 우리는 우리의 목표에 절반 이동할 것입니다. 다음 업데이트에서는 나머지 거리의 절반 (초기 거리의 1/4)을 이동합니다. 다음에 우리는 다시 반을 움직일 것입니다 ...
이는 목표에서 멀어 질 때 움직임이 빠르며 점진적으로 접근함에 따라 점진적으로 느려지는 "지수 적 여유"를 제공합니다 (무한 정도의 숫자를 사용하면 유한 한 수의 업데이트에서는 도달하지 않습니다. 충분히 가까워집니다). 이동 목표 값을 추적하거나 " 지수 이동 평균 "을 사용하여 노이즈 입력을 평활화하는 데 유용합니다. 일반적으로 매우 작 거나 작은 sharpnessPerTick
매개 변수를 사용합니다 0.1
.
그러나 당신이 맞습니다, 당신이 링크 한 공감 답변에 오류가 있습니다. deltaTime
올바른 방법으로 수정하지 않습니다 . 이 스타일을 사용할 때 매우 일반적인 실수입니다 Lerp
.
첫 번째 스타일 Lerp
은 선형이므로 다음을 곱하여 속도를 선형으로 조정할 수 있습니다 deltaTime
.
progress = Mathf.Clamp01(progress + speedPerSecond * Time.deltaTime);
// or progress = Mathf.Clamp01(progress + Time.deltaTime / durationSeconds);
current = Mathf.Lerp(start, end, progress);
그러나 지수 완화는 비선형 이므로 sharpness
매개 변수에 곱 deltaTime
하면 정확한 시간 보정이 제공되지 않습니다. 우리의 프레임 속도가 변동하면 움직임의 판단으로 나타나거나 30에서 60으로 일정하게 유지하면 부드럽게 선명도가 변경됩니다.
대신 우리는 지수 편이성을 위해 지수 수정을 적용해야합니다.
blend = 1f - Mathf.Pow(1f - sharpness, Time.deltaTime * referenceFramerate);
current = Mathf.Lerp(current, target, blend);
여기 에 시간을 수정하기 전에 사용했던 것과 동일한 단위를 유지하는 referenceFramerate
것과 같은 상수가 있습니다 .30
sharpness
이 코드에는 논쟁의 여지가있는 또 다른 오류가 있습니다. Slerp
구형 선형 보간은 전체 움직임을 통해 정확하게 일관된 회전 속도를 원할 때 유용합니다. 그러나 우리가 어쨌든 비선형 지수 편이성을 사용한다면 Lerp
거의 구별 할 수없는 결과를 얻을 것이며 더 저렴합니다. ;) 쿼터니언은 행렬보다 훨씬 뛰어나므로 일반적으로 안전한 대체 방법입니다.