유니티

Lerp와 Time.deltaTime

tose33 2021. 5. 19. 23:51

Mathf.Lerp 함수를 쓰면서 이상한 현상을 발견했다.

카메라의 Field of View를 Lerp를 이용해서 값을 변경했는데 

예를들어 아래와 같이 코드를 작성하면 

 

float goalFiedOfView = 45f;

cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, goalFieldOfView, Time.deltaTime);

 

Field of view가 서서히 45가 되야하는데 44.9... 에서 멈추고 45에 도달하지 않았다.

사실 지금까지 Lerp를 막연히 써왔는데 다시 제대로 찾아봤다.

 

 

https://docs.unity3d.com/kr/530/ScriptReference/Mathf.Lerp.html

 

Unity - 스크립팅 API: Mathf.Lerp

public static function Lerp(a: float, b: float, t: float): float; public static float Lerp(float a, float b, float t);

docs.unity3d.com

 

public static float Lerp(float a, float b, float t)

 

세번째 파라미터인 t는 0에서 1사이의 float 값이다. 

t = 0이라면 a를 반환하고, 

t = 1이라면 b를 반환한다.

따라서 다음과 같이 Time.deltaTime을 파라미터로 Lerp를 쓰면

transform.position = Vector3.Lerp(transform.position, goal.position, Time.deltaTime);

 

Time.deltaTime이 예를들어 0.01이라면 원래 위치인 transform.position과 1프로 떨어져있고, 

목적 위치인 goal.position과 99프로 떨어져있는 위치값 벡터를 반환하는 것이다. 

 

따라서 다음과 같이 쓰면

void Update()
{
	transform.position = Vector3.Lerp(transform.position, goal.position, Time.deltaTime);
}

Update가 반복되면서

첫프레임에서 transform.position의 1프로 떨어진 지점의 벡터를 반환하고 그값이 transform.position이 되고,

다음 프레임에서 또 그 변환된 transform.position에서 1프로 떨어진 지점의 벡터가 반환된다. 

이렇게 Update안에서 계속 반복되면서 서서히 goal.position에 가까워지는 것이다. 

 

이렇게 코드를 쓰게되면 최초의 transform.position에서 goal.position으로 이동은 되지만 정확히 goal.position에 도달하지는 못한다. 예를들어 goal.position이 10이라면 9.997... 이런 값에서 멈춘다. 

 

그 이유는 만약 최초 transform.position이 0이고 goal.position이 10이라고 치자.

그리고 Time.deltaTime이 약 0.01이라고 치자.

그럼 Update문 내부에서 처음에 transform.position이 0에서 1프로 떨어진값으로 바뀔것이고,

그후에 그 바뀐값에서 1프로 떨어진값.. 이런식으로 반복되다가 나중에 transform.position이 99.98까지 왔다고치자.

그럼 그후에 99.98에서 1프로 떨어진값으로 바뀌고 또 바뀌고 또 바뀌지만 1프로 떨어진값씩 계속 바뀌므로 절대 goal.position인 10에 정확히 도달할수는 없다는것을 알수있다.

 

참고:

https://answers.unity.com/questions/14288/can-someone-explain-how-using-timedeltatime-as-t-i.html

 

can someone explain how using Time.deltaTime as 't' in a lerp actually works? - Unity Answers

 

answers.unity.com

 

아래 포스팅에서는 위에서 설명한 3번째 파라미터에 Time.deltaTime을 쓰는방법이 잘못됐다는 것과 올바르게 Lerp를 쓰는 방법이 자세히 나와있다.

https://gamedevbeginner.com/the-right-way-to-lerp-in-unity-with-examples/#right_way_to_use_lerp

 

The right way to Lerp in Unity (with examples) - Game Dev Beginner

Learn to animate buttons, move objects and fade anything - the right way - in my in-depth guide to using LERP in Unity (including copy / paste examples).

gamedevbeginner.com